def updateRecord(self, scanHost): audit._audit().add("sslscan","history",{ "lastUpdate" : self.lastUpdateTime, "endDate" : int(time.time()), "scanHost" : self.scanHost }) self.lastScan = int(time.time()) self.scanHost = scanHost self.update(["lastScan","scanHost"])
def updateRecord(self, bulkClass, eventValues, accuracy, impact, layer, benign, score, expiryTime, history=False): if history: audit._audit().add( "event", "history", { "lastUpdate": self.lastUpdateTime, "endDate": int(time.time()), "expiryTime": self.expiryTime, "eventValues": self.eventValues, "accuracy": self.accuracy, "impact": self.impact, "layer": self.layer, "score": self.score }) self.eventValues = eventValues self.eventFields = list(eventValues.keys()) self.expiryTime = expiryTime self.accuracy = accuracy self.impact = impact self.layer = layer self.benign = benign self.score = score if self._id != "": self.bulkUpdate([ "eventValues", "expiryTime", "eventFields", "accuracy", "impact", "layer", "benign", "score" ], bulkClass)
def api_logout(): response = api.make_response(api.redirect("/login?return=/?")) response.set_cookie("jimiAuth", value="") audit._audit().add("auth", "logout", { "action": "sucess", "_id": api.g["sessionData"]["_id"] }) return response, 302
def updateRecord(self, ip, up): audit._audit().add( "inga", "history", { "lastUpdate": self.lastUpdateTime, "endDate": int(time.time()), "ip": self.ip, "up": self.up }) self.lastScan = int(time.time()) self.ip = ip self.up = up self.update(["lastScan", "ip", "up"])
def validateUser(username, password): user = _user().getAsClass(query={"username": username}) if len(user) == 1: user = user[0] # Account lockout check if (user.failedLoginCount >= 5) and (user.lastLoginAttempt + 60 > time.time()): return None elif user.failedLoginCount >= 5: user.failedLoginCount = 0 user.lastLoginAttempt = time.time() passwordHash = generatePasswordHash(password, username, user.passwordHashType) if passwordHash[1] == user.passwordHash: # If user password hash does not meet the required standard update if user.passwordHashType != requiredhType: passwordHash = generatePasswordHash(password, username) user.passwordHashType = passwordHash[0] user.passwordHash = passwordHash[1] user.update(["passwordHashType", "passwordHash"]) user.failedLoginCount = 0 user.update(["lastLoginAttempt", "failedLoginCount"]) audit._audit().add( "auth", "login", { "action": "sucess", "src_ip": api.request.remote_addr, "username": username, "_id": user._id, "accessIDs": enumerateGroups(user), "primaryGroup": user.primaryGroup, "admin": isAdmin(user) }) return generateSession({ "_id": user._id, "primaryGroup": user.primaryGroup, "admin": isAdmin(user), "accessIDs": enumerateGroups(user), "authenticated": True }) else: user.failedLoginCount += 1 user.update(["lastLoginAttempt", "failedLoginCount"]) audit._audit().add( "auth", "login", { "action": "failed", "src_ip": api.request.remote_addr, "username": username }) return None
def replay(self, keepHistory=False): if self.result == True: return if keepHistory: audit._audit().add( "playbook", "history", { "startTime": self.startTime, "endTime": self.endTime, "result": self.result, "resultData": self.resultData, "version": self.version, "attempt": self.attempt }) self.startTime = int(time.time()) self.endTime = 0 self.resultData = {} self.result = False self.attempt += 1 self.update( ["startTime", "endTime", "resultData", "result", "attempt"])
def newPlay(self, version, keepHistory=False): if keepHistory: audit._audit().add( "playbook", "history", { "startTime": self.startTime, "endTime": self.endTime, "result": self.result, "resultData": self.resultData, "version": self.version, "attempt": self.attempt }) self.version = version self.startTime = int(time.time()) self.endTime = 0 self.resultData = {} self.result = False self.attempt = 0 self.update([ "version", "startTime", "endTime", "resultData", "result", "attempt" ])
def failedTrigger(workerID, failureType, msg=""): triggers = trigger._trigger().query( query={"name": "failedTriggers"})["results"] if len(triggers) > 0: triggerWorkers = trigger._trigger().query( query={"workerID": workerID})["results"] if len(triggerWorkers) > 0: trigger_ = triggers[0] worker_ = triggerWorkers[0] _class = model._model().getAsClass(id=trigger_["classID"]) if len(_class) == 1: _class = _class[0].classObject() if _class: triggerClass = _class().getAsClass(id=trigger_["_id"]) if len(triggerClass) == 1: triggerClass = triggerClass[0] if triggerClass: events = [{ "type": "systemEvent", "eventType": failureType, "workerID": workerID, "triggerID": worker_["_id"], "triggerName": worker_["name"], "msg": msg }] audit._audit().add( "Error", failureType, { "type": "systemEvent", "eventType": failureType, "workerID": workerID, "triggerID": worker_["_id"], "triggerName": worker_["name"], "msg": msg }) # Notify conducts that have a trigger failure trigger within flow workers.workers.new("trigger:{0}".format(trigger_["_id"]), triggerClass.notify, (events, ))
def auditPage(): if api.g["sessionData"]: if "admin" in api.g["sessionData"]: if api.g["sessionData"]["admin"]: auditData = audit._audit().query(query={}, fields=[ "_id", "time", "source", "type", "data", "systemID" ], limit=1000, sort=[("_id", -1)])["results"] auditContent = [] for auditItem in auditData: if "time" in auditItem: auditItem["time"] = time.strftime( '%d/%m/%Y %H:%M:%S', time.gmtime(auditItem["time"])) auditContent.append(auditItem) return render_template("audit.html", content=auditContent) return {}, 403
def updateModelObject(modelName, objectID): class_ = loadModel(modelName) if class_: data = json.loads(api.request.data) if data["action"] == "update": updateItemsList = [] changeLog = {} data = data["data"] _class = class_.classObject()().getAsClass( api.g["sessionData"], id=objectID) if len(_class) == 1: _class = _class[0] # Builds list of permitted ACL access, accessIDs, adminBypass = db.ACLAccess( api.g["sessionData"], _class.acl, "write") if access: for dataKey, dataValue in data.items(): fieldAccessPermitted = True # Checking if sessionData is permitted field level access if _class.acl and not adminBypass: fieldAccessPermitted = db.fieldACLAccess( api.g["sessionData"], _class.acl, dataKey, "write") if fieldAccessPermitted: # _id is a protected mongodb object and cant be updated if dataKey != "_id": if hasattr(_class, dataKey): changeLog[dataKey] = {} changeLog[dataKey][ "currentValue"] = getattr( _class, dataKey) if type(getattr(_class, dataKey)) is str: if dataValue: if _class.setAttribute( dataKey, str(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append( dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr(_class, dataKey)) is int: try: if _class.setAttribute( dataKey, int(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append( dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) except ValueError: if _class.setAttribute( dataKey, 0, sessionData=api. g["sessionData"]): updateItemsList.append( dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr( _class, dataKey)) is float: try: if _class.setAttribute( dataKey, float(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append( dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) except ValueError: if _class.setAttribute( dataKey, 0, sessionData=api. g["sessionData"]): updateItemsList.append( dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr( _class, dataKey)) is bool: # Convert string object to bool if type(dataValue) is str: if dataValue.lower( ) == "true": dataValue = True else: dataValue = False if _class.setAttribute( dataKey, dataValue, sessionData=api. g["sessionData"]): updateItemsList.append( dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr( _class, dataKey)) is dict or type( getattr( _class, dataKey)) is list: if dataValue: if _class.setAttribute( dataKey, json.loads( dataValue), sessionData=api. g["sessionData"]): updateItemsList.append( dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) # Commit back to database if updateItemsList: _class.update(updateItemsList) # Adding audit record if "_id" in api.g["sessionData"]: audit._audit().add( "model", "update", { "_id": api.g["sessionData"]["_id"], "objects": helpers.unicodeEscapeDict( changeLog) }) else: audit._audit().add( "model", "update", { "objects": helpers.unicodeEscapeDict( changeLog) }) return {}, 200 else: return {}, 403 return {}, 404
def setConductFlow(conductID, flowID): # List of attributes that are prevented from updating - this needs to be made more dynamic and part of class design unsafeUpdateList = [ "_id", "classID", "lastCheck", "lastRun", "lastResult", "workerID", "startCheck" ] conductObj = conduct._conduct().query(api.g["sessionData"], id=conductID)["results"] conductObj = conductObj[0] conductObj = conduct._conduct().getAsClass(api.g["sessionData"], id=conductObj["_id"]) if len(conductObj) == 1: conductObj = conductObj[0] else: return {}, 404 flow = [x for x in conductObj.flow if x["flowID"] == flowID] if len(flow) == 1: flow = flow[0] data = json.loads(api.request.data) modelFlowObject = None # Check if the modelType and object are unchanged if "type" in flow: if flow["type"] == "trigger": modelFlowObject = trigger._trigger().getAsClass( api.g["sessionData"], id=flow["{0}{1}".format(flow["type"], "ID")]) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] modelFlowObjectType = "trigger" if flow["type"] == "action": modelFlowObject = action._action().getAsClass( api.g["sessionData"], id=flow["{0}{1}".format(flow["type"], "ID")]) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] modelFlowObjectType = "action" # Was it possible to load an existing object if modelFlowObject: # Check that the object model is still the same if modelFlowObject.classID == data["newClassID"]: # Get flow object correct class _class = model._model().getAsClass( api.g["sessionData"], id=modelFlowObject.classID) if len(_class) == 1: _class = _class[0] _class = _class.classObject() else: return {}, 404 modelFlowObject = _class().getAsClass( api.g["sessionData"], id=modelFlowObject._id) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] else: return {}, 404 else: modelFlowObject = None # New object required if not modelFlowObject: _class = model._model().getAsClass(api.g["sessionData"], id=data["newClassID"]) if _class: _class = _class[0].classObject() # Bug exists as name value is not requried by db class but is for core models - this could result in an error if new model is added that does not accept name within new function override newFlowObjectID = _class().new(flow["flowID"]).inserted_id # Working out by bruteforce which type this is ( try and load it by parent class and check for error) - get on trigger if it does not exist will return None modelFlowObjectType = "action" if len(trigger._trigger().getAsClass(api.g["sessionData"], id=newFlowObjectID)) > 0: modelFlowObjectType = "trigger" modelFlowObject = _class().getAsClass(api.g["sessionData"], id=newFlowObjectID) if len(modelFlowObject) == 1: modelFlowObject = modelFlowObject[0] else: return {}, 404 modelFlowObject.acl = { "ids": [{ "accessID": api.g["sessionData"]["primaryGroup"], "read": True, "write": True, "delete": True }] } modelFlowObject.update(["acl"]) # Set conduct flow to correct type and objectID flow["type"] = modelFlowObjectType flow["{0}{1}".format(modelFlowObjectType, "ID")] = str(newFlowObjectID) conductObj.update(["flow"], sessionData=api.g["sessionData"]) # Updating new or existing modeFlowObject if modelFlowObject: updateItemsList = [] changeLog = {} # Getting schema information so types can be set correctly class_ = model._model().getAsClass(api.g["sessionData"], id=modelFlowObject.classID) if class_: _class = modelFlowObject # Builds list of permitted ACL access, accessIDs, adminBypass = db.ACLAccess( api.g["sessionData"], _class.acl, "write") if access: for dataKey, dataValue in data.items(): fieldAccessPermitted = True # Checking if sessionData is permitted field level access if _class.acl and not adminBypass: fieldAccessPermitted = db.fieldACLAccess( api.g["sessionData"], _class.acl, dataKey, "write") if fieldAccessPermitted: # Change update database entry _id if dataKey not in unsafeUpdateList: if hasattr(_class, dataKey): changeLog[dataKey] = {} changeLog[dataKey][ "currentValue"] = getattr( _class, dataKey) if type(getattr(_class, dataKey)) is str: if dataValue: if _class.setAttribute( dataKey, str(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr(_class, dataKey)) is int: try: if _class.setAttribute( dataKey, int(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) except ValueError: if _class.setAttribute( dataKey, 0, sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr(_class, dataKey)) is float: try: if _class.setAttribute( dataKey, float(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) except ValueError: if _class.setAttribute( dataKey, 0, sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr(_class, dataKey)) is bool: if _class.setAttribute( dataKey, bool(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) elif type(getattr( _class, dataKey)) is dict or type( getattr(_class, dataKey)) is list: if dataValue: if _class.setAttribute( dataKey, json.loads(dataValue), sessionData=api. g["sessionData"]): updateItemsList.append(dataKey) changeLog[dataKey][ "newValue"] = getattr( _class, dataKey) # Commit back to database if updateItemsList: _class.update(updateItemsList, sessionData=api.g["sessionData"]) # Adding audit record if "_id" in api.g["sessionData"]: audit._audit().add( "model", "update", { "_id": api.g["sessionData"]["_id"], "objects": helpers.unicodeEscapeDict(changeLog) }) else: audit._audit().add("model", "update", { "objects": helpers.unicodeEscapeDict(changeLog) }) return {"type": modelFlowObjectType}, 200 else: return {}, 403 return {}, 404
def doAction(self, data): ip = helpers.evalString(self.ip, {"data": data["flowData"]}) if ip: ports = helpers.evalString(self.ports, {"data": data["flowData"]}) scanName = helpers.evalString(self.scanName, {"data": data["flowData"]}) options = ["nmap"] if ports.startswith("--"): options.append(ports.split(" ")[0]) options.append(ports.split(" ")[1]) else: options.append("-p") options.append(ports) options.append(ip) scan = inga._inga().getAsClass(query={ "scanName": scanName, "ip": ip }) if len(scan) > 0: scan = scan[0] else: scanID = inga._inga().new(self.acl, scanName, ip, True).inserted_id scan = inga._inga().getAsClass(id=scanID)[0] if scan: timeout = 30 if self.timeout > 0: timeout = self.timeout # Support for running on a remote host if self.runRemote and "remote" in data["eventData"]: if "client" in data["eventData"]["remote"]: client = data["eventData"]["remote"]["client"] exitCode, stdout, stderr = client.command( " ".join(options), elevate=True) stdout = "\n".join(stdout) stderr = "\n".join(stderr) if not stdout: return {"result": False, "rc": 500, "msg": stderr} else: process = subprocess.Popen(options, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) try: stdout, stderr = process.communicate(timeout=timeout) stdout = stdout.decode() stderr = stderr.decode() except subprocess.TimeoutExpired: return {"result": False, "rc": -999} openPorts = re.finditer(r'^(\d*)\/(\S*)\s*(\S*)\s*([^\n]*)$', stdout, re.MULTILINE) updates = {"new": [], "update": [], "removed": []} foundPorts = [] #udp = [ x["port"] for x in scan.ports["udp"] ] for index, logicMatch in enumerate(openPorts): portNumber = int(logicMatch.group(1).strip()) portType = logicMatch.group(2).strip() portState = logicMatch.group(3).strip() portService = logicMatch.group(4).strip() currentPort = [ x for x in scan.ports["tcp"] if x["port"] == portNumber ] if currentPort: currentPort = currentPort[0] portDict = { "port": portNumber, "type": portType, "state": portState, "service": portService, "data": {}, "lastSeen": time.time() } if portNumber not in foundPorts: foundPorts.append(portNumber) if not currentPort: updates["new"].append(portDict) else: if currentPort["state"] != portDict[ "state"] or currentPort[ "service"] != portDict["service"]: updates["update"].append(portDict) elif not self.stateChange: updates["update"].append(portDict) poplist = [] try: for port in [x["port"] for x in scan.ports["tcp"]]: if port not in foundPorts: poplist.append(port) for port in poplist: currentPort = [ x for x in scan.ports["tcp"] if x["port"] == port ] if currentPort: currentPort = currentPort[0] updates["removed"].append(currentPort) except KeyError: pass scan.ports["scanDetails"]["lastPortScan"] = time.time() scan.update(["ports"]) if len(updates["new"]) > 0 or len(updates["update"]) > 0: audit._audit().add( "inga", "history", { "lastUpdate": scan.lastUpdateTime, "endDate": int(time.time()), "ip": scan.ip, "up": scan.up, "ports": scan.ports }) actionResult = {} actionResult["result"] = True actionResult["rc"] = 0 actionResult["data"]["portScan"] = updates bulkOps = scan._dbCollection.initialize_ordered_bulk_op() if len(updates["update"]) > 0: actionResult["rc"] = 302 for port in updates["update"]: bulkOps.find({ "scanName": scanName, "ip": ip, "ports.tcp.port": port["port"] }).update_one({ "$set": { "ports.tcp.$.state": port["state"], "ports.tcp.$.service": port["service"] } }) if len(updates["new"]) > 0: actionResult["rc"] = 201 for port in updates["new"]: bulkOps.find({ "scanName": scanName, "ip": ip }).update_one({"$push": { "ports.tcp": port }}) for port in updates["removed"]: bulkOps.find({ "scanName": scanName, "ip": ip, "ports.tcp.port": port["port"] }).update_one( {"$pull": { "ports.tcp": { "port": port["port"] } }}) if len(updates["new"]) > 0 or len( updates["update"]) > 0 or len(updates["removed"]) > 0: bulkOps.execute() if actionResult["rc"] == 0 and len(foundPorts) > 0: actionResult["rc"] = 304 return actionResult actionResult["result"] = False actionResult["rc"] = 1 return actionResult