def doAction(self, data): actionResult = {} scanName = helpers.evalString(self.scanName, {"data": data["flowData"]}) customSearch = helpers.evalDict(self.customSearch, {"data": data["flowData"]}) if scanName != "": search = {"scanName": scanName} else: search = {} if customSearch: for key, value in customSearch.items(): search[key] = value actionResult["result"] = True actionResult["rc"] = 0 if self.limit > 0: actionResult["events"] = inga._inga().query( query=search, limit=self.limit, sort=[("ports.scanDetails.lastPortScan", 1)])["results"] else: actionResult["events"] = inga._inga().query( query=search, sort=[("ports.scanDetails.lastPortScan", 1)])["results"] return actionResult
def run(self,data,persistentData,actionResult): ip = helpers.evalString(self.ip,{"data" : data}) domain = helpers.evalString(self.domain,{"data" : data}) scanName = helpers.evalString(self.scanName,{"data" : data}) scanResult = inga._inga().getAsClass(query={ "scanName" : scanName, "ip" : ip },fields=["scanName","ip","domains"]) if len(scanResult) == 1: scanResult = scanResult[0] domainFound = False for domainKey,domainItem in scanResult.domains.items(): if domainItem["domain"] == domain: domainFound = True break if not domainFound: scanResult._dbCollection.update_one({ "scanName" : scanName, "ip" : ip },{ "$push" : { "domains" : { "domain" : domain, "ip" : ip, "lastSeen" : time.time() } } }) actionResult["result"] = True actionResult["rc"] = 0 elif len(scanResult) == 0: newId = inga._inga().new(self.acl,scanName,str(ip),False) scanResult = inga._inga().getAsClass(id=str(newId.inserted_id),fields=["scanName","ip","domains"]) scanResult.domains.append({ "domain" : domain, "ip" : ip, "lastSeen" : time.time() }) scanResult.update(["domains"]) actionResult["result"] = True actionResult["rc"] = 201 else: actionResult["result"] = False actionResult["rc"] = 502 return actionResult
def doAction(self,data): actionResult = {} ip = helpers.evalString(self.ip,{"data" : data["flowData"]}) port = helpers.evalString(self.port,{"data" : data["flowData"]}) scanName = helpers.evalString(self.scanName,{"data" : data["flowData"]}) domainName = helpers.evalString(self.domainName,{"data" : data["flowData"]}) result = [] protocols = ["http", "https"] for protocol in protocols: timeout = 5 if self.timeout != 0: timeout = self.timeout response = remoteHelpers.runRemoteFunction(self.runRemote,data["eventData"],webserverConnect,{"protocol" : protocol, "ip" : ip, "port" : port, "timeout" : timeout, "domainName" : domainName},False) if "error" not in response: headers = helpers.lower_dict(response["headers"]) for excludeHeader in self.excludeHeaders: if excludeHeader in headers: del headers[excludeHeader] # Update scan if updateScan mapping was provided if len(scanName) > 0: if domainName == "": inga._inga()._dbCollection.update_one({ "scanName": scanName, "ip": ip, "ports.tcp.port" : port },{ "$set" : { "ports.tcp.$.data.webServerDetect" : { "protocol" : protocol, "headers" : headers, "lastSeen" : time.time() } } }) url = "{0}://{1}:{2}".format(protocol,ip,port) else: inga._inga()._dbCollection.update_one({ "scanName": scanName, "ip": ip, "domains.domain" : domainName },{ "$set" : { "domains.$.data.webServerDetect.{0}".format(protocol) : { "protocol" : protocol, "headers" : headers, "lastSeen" : time.time() } } }) url = "{0}://{1}".format(protocol,domainName) # Detect HTTP -> HTTPS redirect upgrade insecureUpgrade = None try: if protocol == "http" and "https://" in headers["location"]: insecureUpgrade = True except KeyError: if protocol == "http": insecureUpgrade = False result.append({ "protocol" : protocol, "headers" : headers, "url" : url, "insecureUpgrade" : insecureUpgrade }) else: actionResult["result"] = False actionResult["rc"] = 500 actionResult["msg"] = response["error"] actionResult["stderr"] = response["stderr"] actionResult["stdout"] = response["stdout"] return actionResult if result: actionResult["result"] = True actionResult["rc"] = 0 actionResult["serverDetails"] = result else: actionResult["result"] = False actionResult["rc"] = 404 return actionResult
def check(self): search = {"scanName": self.scanName, "up": True} if self.customSearch: for key, value in self.customSearch.items(): search[key] = value if self.limit > 0: self.result["events"] = inga._inga().query( query=search, limit=self.limit, sort=[("ports.scanDetails.lastPortScan", 1)])["results"] else: self.result["events"] = inga._inga().query( query=search, sort=[("ports.scanDetails.lastPortScan", 1)])["results"]
def barScansResults(): bar = ui.bar() with open(Path("plugins/inga/web/includes/sankeyMapping.json")) as json_file: serviceMap = json.load(json_file) bar.addLabel("Other") for service in serviceMap.keys(): bar.addLabel(service) scansResults = inga._inga().getAsClass(api.g.sessionData,query={ "up" : True },fields=["scanName","ip","up","lastScan","ports"]) data = {} for scansResult in scansResults: if scansResult.scanName not in data: data[scansResult.scanName] = { "Other" : 0 } for service in serviceMap.keys(): data[scansResult.scanName][service] = 0 for port in scansResult.ports["tcp"]: matched = getPortMapping(serviceMap,str(port["port"])) if matched != None: data[scansResult.scanName][matched] += 1 else: data[scansResult.scanName]["Other"] += 1 for scan in data: dataList = [] for k,v in data[scan].items(): dataList.append(v) bar.addDataset(scan,dataList) data = json.loads(jimi.api.request.data) return bar.generate(data), 200
def run(self, data, persistentData, actionResult): ip = helpers.evalString(self.ip, {"data": data}) domain = helpers.evalString(self.domain, {"data": data}) scanName = helpers.evalString(self.scanName, {"data": data}) scanResult = inga._inga().getAsClass( query={ "scanName": scanName, "ip": ip, "domains.domain": domain }, fields=["scanName", "ip", "domains"]) if len(scanResult) == 1: scanResult = scanResult[0] scanResult._dbCollection.update_one( { "scanName": scanName, "ip": ip, "domains.domain": domain }, {"$pull": { "domains": { "domain": domain } }}) actionResult["result"] = True actionResult["rc"] = 200 else: actionResult["result"] = False actionResult["rc"] = 502 return actionResult
def getScanImages(scanName): results = inga._inga().query(api.g.sessionData,query={ "scanName" : scanName, "up" : True },fields=["ports","ip","domains"])["results"] result = [] ids = [] for scan in results: try: for portValue in scan["ports"]["tcp"]: try: ids.append(db.ObjectId(portValue["data"]["webScreenShot"]["storageID"])) result.append({ "url" : "{0}://{1}:{2}".format(portValue["data"]["webServerDetect"]["protocol"],scan["ip"],portValue["port"]), "fileData" : portValue["data"]["webScreenShot"]["storageID"] }) except KeyError: pass for domainValue in scan["domains"]: for protocol in ["http","https"]: try: ids.append(db.ObjectId(domainValue["data"]["webScreenShot"][protocol]["storageID"])) result.append({ "url" : "{0}://{1}".format(protocol,domainValue["domain"]), "fileData" : domainValue["data"]["webScreenShot"][protocol]["storageID"] }) except KeyError: pass except KeyError: pass results = storage._storage().query(api.g.sessionData,query={ "_id" : { "$in" : ids } })["results"] for item in result: for storageResult in results: if item["fileData"] == str(storageResult["_id"]): item["fileData"] = storageResult["fileData"] return render_template("scanImages.html", result=result)
def timelineScansResults(scanName): scanResults = inga._inga().getAsClass(api.g.sessionData,query={ "scanName" : scanName, "up" : True },fields=["scanName","ip","up","lastScan","ports"]) timeline = [] for scanResult in scanResults: formatted_date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(scanResult.lastScan)) timeline.append({ "id" : len(timeline), "content" : scanResult.ip, "start" : formatted_date }) return { "timeline" : timeline }, 200
def doAction(self,data): actionResult = {} scanName = helpers.evalString(self.scanName,{"data" : data["flowData"]}) topLevelDomain = helpers.evalString(self.topLevelDomain,{"data" : data["flowData"]}) response = remoteHelpers.runRemoteFunction(self.runRemote,data["eventData"],runtheHarvester,{"topLevelDomain" : topLevelDomain},False) if "error" not in response: if len(scanName) > 0: scanResults = inga._inga().getAsClass(query={ "scanName" : scanName },fields=["scanName","ip","up","lastScan","domains"]) for domain in response["domains"]: if domain["ip"] != "": scanFound = False for scanResult in scanResults: if scanResult.ip == domain["ip"]: currentEntry = scanResult scanFound = True break if not scanFound: newId = str(inga._inga().new(self.acl,scanName,domain["ip"],False).inserted_id) newEntry = inga._inga().getAsClass(id=newId)[0] scanResults.append(newEntry) currentEntry = newEntry currentEntryDomainFound = False for currentEntryDomain in currentEntry.domains: if currentEntryDomain["domain"] == domain["domain"]: currentEntryDomainFound = True currentEntry._dbCollection.update_one({ "scanName" : scanName, "ip" : domain["ip"], "domains.domain" : domain["domain"] },{ "$set" : { "domains.$.lastSeen" : domain["lastSeen"] } }) break if not currentEntryDomainFound: currentEntry.domains.append(domain) currentEntry._dbCollection.update_one({ "scanName" : scanName, "ip" : domain["ip"] },{ "$push" : { "domains" : domain } }) actionResult["result"] = True actionResult["rc"] = 0 actionResult["domains"] = response["domains"] else: actionResult["result"] = False actionResult["rc"] = 500 actionResult["msg"] = response["error"] actionResult["stderr"] = response["stderr"] actionResult["stdout"] = response["stdout"] return actionResult
def doAction(self,data): actionResult = {} ip = helpers.evalString(self.ip,{"data" : data["flowData"]}) port = helpers.evalString(self.port,{"data" : data["flowData"]}) scanName = helpers.evalString(self.scanName,{"data" : data["flowData"]}) url = helpers.evalString(self.url,{"data" : data["flowData"]}) domainName = helpers.evalString(self.domainName,{"data" : data["flowData"]}) outputDir = helpers.evalString(self.outputDir,{"data" : data["flowData"]}) timeout = 5 if self.timeout != 0: timeout = self.timeout response = remoteHelpers.runRemoteFunction(self.runRemote,data["eventData"],takeScreenshot,{"url" : url, "timeout" : timeout, "outputDir" : outputDir},False) if "error" not in response: # check for existing screenshot and delete it scan = inga._inga().getAsClass(query={ "scanName": scanName, "ip": ip }) if len(scan) > 0: scan = scan[0] try: for scanPort in scan.ports["tcp"]: if scanPort["port"] == port: storage._storage().api_delete(id=scanPort["data"]["webScreenShot"]["storageID"]) except KeyError: pass newStorageItem = storage._storage().new(self.acl,"_ingaWebScreenShot",response["fileData"]) if domainName == "": inga._inga()._dbCollection.update_one({ "scanName": scanName, "ip": ip, "ports.tcp.port" : port },{ "$set" : { "ports.tcp.$.data.webScreenShot" : { "storageID" : str(newStorageItem.inserted_id), "lastSeen" : time.time() } } }) else: protocol = "http" if "https://" in url: protocol = "https" inga._inga()._dbCollection.update_one({ "scanName": scanName, "ip": ip, "domains.domain" : domainName },{ "$set" : { "domains.$.data.webScreenShot.{0}".format(protocol) : { "storageID" : str(newStorageItem.inserted_id), "lastSeen" : time.time() } } }) actionResult["result"] = True actionResult["rc"] = 0 actionResult["storageID"] = str(newStorageItem.inserted_id) else: actionResult["result"] = False actionResult["rc"] = 500 actionResult["msg"] = response["error"] actionResult["stderr"] = response["stderr"] actionResult["stdout"] = response["stdout"] return actionResult
def run(self,data,persistentData,actionResult): cidr = helpers.evalString(self.cidr,{"data" : data}) scanName = helpers.evalString(self.scanName,{"data" : data}) ips = IPNetwork(cidr) scanResults = inga._inga().query(query={ "scanName" : scanName },fields=["scanName","ip"])["results"] newIPs = [] for ip in ips: ipFound = False for scanResult in scanResults: if str(ip) == scanResult["ip"]: ipFound = True if not ipFound: inga._inga().new(self.acl,scanName,str(ip),False) newIPs.append(str(ip)) actionResult["result"] = True actionResult["rc"] = 0 actionResult["added"] = newIPs return actionResult
def run(self,data,persistentData,actionResult): ip = helpers.evalString(self.ip,{"data" : data}) scanName = helpers.evalString(self.scanName,{"data" : data}) scanResult = inga._inga().getAsClass(query={ "scanName" : scanName, "ip" : ip },fields=["scanName","ip"]) if len(scanResult) == 1: scanResult = scanResult[0] scanResult.delete() actionResult["result"] = True actionResult["rc"] = 0 else: actionResult["result"] = False actionResult["rc"] = 502 return actionResult
def tableScans(action): scans = inga._inga().groupby(sessionData=api.g.sessionData,field="scanName") total = len(scans) columns = [ "Scan Name", "Total Hosts" ] table = ui.table(columns,total,total) if action == "build": return table.getColumns() ,200 elif action == "poll": # Custom table data so it can be vertical data = [] for source in scans: data.append(["<a href=\"{0}{1}/\">{2}</a>".format("scan/",source["_id"],ui.safe(source["_id"])),ui.safe(source["_count"])]) table.data = data return { "draw" : int(jimi.api.request.args.get('draw')), "recordsTable" : total, "recordsFiltered" : total, "recordsTotal" : total, "data" : data } ,200
def tableScansDomains(action): scans = inga._inga().getAsClass(sessionData=api.g.sessionData,query={}) columns = [ "Domain Name", "IP", "Scan Name" ] table = ui.table(columns,0,0) if action == "build": return table.getColumns() ,200 elif action == "poll": data = [] for scan in scans: for domain in scan.domains: data.append([ui.safe(domain["domain"]),ui.safe(domain["ip"]),ui.safe(scan.scanName)]) total = len(data) start = int(jimi.api.request.args.get('start')) if start + 200 > len(data): data = data[start:] else: data = data[start:start+200] return { "draw" : int(jimi.api.request.args.get('draw')), "recordsTable" : len(data), "recordsFiltered" : total, "recordsTotal" : total, "data" : data } ,200
def check(self): ips = IPNetwork(self.cidr) if self.scanQuantity == 0: scanQuantity = len(ips) else: scanQuantity = self.scanQuantity scanResults = inga._inga().query( query={"scanName": self.scanName})["results"] for ip in ips: ipFound = False for scanResult in scanResults: if str(ip) == scanResult["ip"]: ipFound = True if not ipFound: inga._inga().new(self.scanName, str(ip), False) if self.lastScanAtleast > 0: scanResults = inga._inga().getAsClass(query={ "scanName": self.scanName, "lastScan": { "$lt": (time.time() - self.lastScanAtleast) } }, limit=scanQuantity, sort=[("lastScan", 1)]) else: scanResults = inga._inga().getAsClass( query={"scanName": self.scanName}, limit=scanQuantity, sort=[("lastScan", 1)]) discovered = [] for scanResult in scanResults: process = subprocess.Popen([ "nmap", "-sn", "--max-rtt-timeout", "800ms", "--max-retries", "0", scanResult.ip ], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() change = False if "Host is up (" in stdout.decode(): if scanResult.up != True: scanResult.updateRecord(scanResult.ip, True) change = True if not self.stateChange or change: discovered.append({ "ip": scanResult.ip, "up": True, "scanName": self.scanName }) else: process = subprocess.Popen([ "nmap", "--top-ports", "100", "-Pn", "--max-rtt-timeout", "800ms", "--max-retries", "0", "--open", scanResult.ip ], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() openPorts = re.finditer(r'^(\d*)\/(\S*)\s+(open)\s+([^\n]*)$', stdout, re.MULTILINE) up = False for index, logicMatch in enumerate(openPorts): up = True break if up: if scanResult.up != True: scanResult.updateRecord(scanResult.ip, True) change = True if not self.stateChange or change: discovered.append({ "ip": scanResult.ip, "up": True, "scanName": self.scanName }) else: process = subprocess.Popen([ "nmap", "-sU", "--top-ports", "10", "-Pn", "--max-rtt-timeout", "800ms", "--max-retries", "0", "--open", scanResult.ip ], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() openPorts = re.finditer( r'^(\d*)\/(\S*)\s+(open)\s+([^\n]*)$', stdout, re.MULTILINE) up = False for index, logicMatch in enumerate(openPorts): up = True break if up: if scanResult.up != True: scanResult.updateRecord(scanResult.ip, True) change = True if not self.stateChange or change: discovered.append({ "ip": scanResult.ip, "up": True, "scanName": self.scanName }) else: if scanResult.up != False: scanResult.updateRecord(scanResult.ip, False) change = True if not self.stateChange or change: discovered.append({ "ip": scanResult.ip, "up": False, "scanName": self.scanName }) if not change: scanResult.lastScan = int(time.time()) scanResult.update(["lastScan"]) self.result["events"] = discovered
def mainPage(): # unsecurePorts,fileTransferPorts,rdp,webserverPorts,databasePorts,networkProtoPorts,otherPort = 0,0,0,0,0,0,0 scans = inga._inga()._dbCollection.distinct("scanName") results = [] sankeyChartData = [] portsPieChart = {} jsonMappingFile = abspath( join(dirname(__file__), '..', 'web') ) + "/includes/sankeyMapping.json" #dirname(abspath(__file__)) + "/sankeyMapping.json" #abspath(join(dirname( __file__ ), '..'))#, 'includes')) # with open(jsonMappingFile) as json_file: jsonMap_data = load(json_file) for scan in scans: #reset keys for each scan sankeyDict = { "unsecurePorts": 0, "fileTransferPorts": 0, "rdp": 0, "webserverPorts": 0, "databasePorts": 0, "networkProtoPorts": 0, "otherPort": 0 } scanData = inga._inga().query(api.g.sessionData, query={ "scanName": scan, "up": True })["results"] totalCount = inga._inga().count(api.g.sessionData, query={"scanName": scan})["results"][0]["count"] upCount = inga._inga().count(api.g.sessionData, query={ "scanName": scan, "up": True })["results"][0]["count"] for upHost in scanData: if "cidr" in upHost and upHost["cidr"] != "": # print(upHost) tcpPorts = upHost["ports"]["tcp"] udpPorts = upHost["ports"]["udp"] try: for portValue in tcpPorts: if portValue["port"] not in portsPieChart: portsPieChart[portValue["port"]] = 0 if portValue["state"] == "open": portsPieChart[portValue["port"]] += 1 except KeyError: pass #merge both lists together combinedPorts = tcpPorts + udpPorts for port in combinedPorts: if port["state"] == "open": portNum = port["port"] matched = getPortMapping(jsonMap_data, str(portNum)) # print(matched) if matched != None: sankeyDict[matched] += 1 else: sankeyDict["otherPort"] += 1 for k, v in sankeyDict.items(): if v > 0: scanName = scanData[0]["scanName"] sankeyChartData.append([scanName, k, v]) if totalCount > 0: results.append({ "scanName": scan, "up": upCount, "total": totalCount }) pieChartColours = genRandomColours(len(portsPieChart)) # print(pieChartColours) # print(portsPieChart) # print(sankeyChartData) return render_template("ingaHomepage.html", scans=results, sankeyPortData=sankeyChartData, pieChart=portsPieChart, pieChartColours=pieChartColours)
def getScan(): scanName = urllib.parse.unquote_plus(request.args.get("scanName")) results = inga._inga().query( api.g.sessionData, query={ "scanName": scanName, "up": True }, fields=["scanName", "ip", "up", "lastScan", "ports"])["results"] barChartData = {} scanData = [] networkChartPorts = [] # # New for scan in results: c = 0 portValues = [] try: tcpPorts = scan["ports"]["tcp"] udpPorts = scan["ports"]["udp"] combinedPorts = tcpPorts + udpPorts for portValue in combinedPorts: if portValue["state"] == "open": c += 1 portValues.append({ "port": portValue["port"], "service": portValue["service"], "state": portValue["state"] }) networkChartPorts.append( [scan["ip"], str(portValue["port"])]) if c > 0: try: barChartData[scan["ip"]] = c except KeyError: pass except KeyError: pass scanData.append({ "scanName": scan["scanName"], "ip": scan["ip"], "up": scan["up"], "lastScan": scan["lastScan"], "portData": portValues }) barChartColours = genRandomColours(len(barChartData)) test = inga._inga().query(api.g.sessionData, query={ "scanName": scanName, "up": True }, fields=["ports", "ip", "domains"])["results"] test2 = [] ids = [] print(scanName) for scan in test: # print(scan) try: for portValue in scan["ports"]["tcp"]: try: ids.append( db.ObjectId( portValue["data"]["webScreenShot"]["storageID"])) test2.append({ "url": "{0}://{1}:{2}".format( portValue["data"]["webServerDetect"]["protocol"], scan["ip"], portValue["port"]), "fileData": portValue["data"]["webScreenShot"]["storageID"] }) except KeyError: pass for domainValue in scan["domains"]: for protocol in ["http", "https"]: try: ids.append( db.ObjectId(domainValue["data"]["webScreenShot"] [protocol]["storageID"])) test2.append({ "url": "{0}://{1}".format(protocol, domainValue["domain"]), "fileData": domainValue["data"]["webScreenShot"][protocol] ["storageID"] }) except KeyError: pass except KeyError: pass print("IDS", ids) print(test2) results = storage._storage().query(api.g.sessionData, query={"_id": { "$in": ids }})["results"] for item in test2: for storageResult in results: if item["fileData"] == str(storageResult["_id"]): item["fileData"] = storageResult["fileData"] return render_template("ingaScan.html", barChartData=barChartData, barChartColours=barChartColours, scanData=scanData, networkChartPorts=networkChartPorts)
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
def doAction(self, data): cidr = helpers.evalString(self.cidr, {"data": data["flowData"]}) scanName = helpers.evalString(self.scanName, {"data": data["flowData"]}) scanQuantity = self.scanQuantity try: ips = IPNetwork(cidr) if self.scanQuantity == 0: scanQuantity = len(ips) scanResults = inga._inga().query( query={"scanName": scanName}, fields=["scanName", "ip", "up", "lastScan"])["results"] for ip in ips: ipFound = False for scanResult in scanResults: if str(ip) == scanResult["ip"]: ipFound = True if not ipFound: inga._inga().new(self.acl, scanName, str(ip), False, cidr=cidr) except: pass if scanName != "": if self.lastScanAtLeast > 0: scanResults = inga._inga().getAsClass( query={ "scanName": scanName, "lastScan": { "$lt": (time.time() - self.lastScanAtLeast) } }, limit=scanQuantity, sort=[("lastScan", 1)], fields=["scanName", "ip", "up", "lastScan"]) else: scanResults = inga._inga().getAsClass( query={"scanName": scanName}, limit=scanQuantity, sort=[("lastScan", 1)], fields=["scanName", "ip", "up", "lastScan"]) else: # If no scanName is given then return results from all scans if self.lastScanAtLeast > 0: scanResults = inga._inga().getAsClass( query={ "lastScan": { "$lt": (time.time() - self.lastScanAtLeast) } }, limit=scanQuantity, sort=[("lastScan", 1)], fields=["scanName", "ip", "up", "lastScan"]) else: scanResults = inga._inga().getAsClass( query={}, limit=scanQuantity, sort=[("lastScan", 1)], fields=["scanName", "ip", "up", "lastScan"]) discovered = [] for scanResult in scanResults: # 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([ "nmap", "-sn", "--max-rtt-timeout", "800ms", "--max-retries", "0", scanResult.ip ]), elevate=True) stdout = "\n".join(stdout) stderr = "\n".join(stderr) if not stdout: return {"result": False, "rc": 500, "msg": stderr} else: process = subprocess.Popen([ "nmap", "-sn", "--max-rtt-timeout", "800ms", "--max-retries", "0", scanResult.ip ], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() stdout = stdout.decode() stderr = stderr.decode() change = False if "Host is up (" in stdout: if scanResult.up != True: scanResult.updateRecord(scanResult.ip, True) change = True if not self.stateChange or change: discovered.append({ "ip": scanResult.ip, "up": True, "scanName": scanResult.scanName }) elif self.pingOnly == False: 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([ "nmap", "--top-ports", "100", "-Pn", "--max-rtt-timeout", "800ms", "--max-retries", "0", scanResult.ip ]), elevate=True) stdout = "\n".join(stdout) stderr = "\n".join(stderr) if not stdout: return {"result": False, "rc": 500, "msg": stderr} else: process = subprocess.Popen([ "nmap", "--top-ports", "100", "-Pn", "--max-rtt-timeout", "800ms", "--max-retries", "0", scanResult.ip ], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() stdout = stdout.decode() stderr = stderr.decode() openPorts = re.finditer(r'^(\d*)\/(\S*)\s+(open)\s+([^\n]*)$', stdout, re.MULTILINE) up = False for index, logicMatch in enumerate(openPorts): up = True break if up: if scanResult.up != True: scanResult.updateRecord(scanResult.ip, True) change = True if not self.stateChange or change: discovered.append({ "ip": scanResult.ip, "up": True, "scanName": scanResult.scanName }) else: 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([ "nmap", "-sU", "--top-ports", "10", "-Pn", "--max-rtt-timeout", "800ms", "--max-retries", "0", scanResult.ip ]), elevate=True) stdout = "\n".join(stdout) stderr = "\n".join(stderr) if not stdout: return { "result": False, "rc": 500, "msg": stderr } else: process = subprocess.Popen([ "nmap", "-sU", "--top-ports", "10", "-Pn", "--max-rtt-timeout", "800ms", "--max-retries", "0", scanResult.ip ], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = process.communicate() stdout = stdout.decode() stderr = stderr.decode() openPorts = re.finditer( r'^(\d*)\/(\S*)\s+(open)\s+([^\n]*)$', stdout, re.MULTILINE) up = False for index, logicMatch in enumerate(openPorts): up = True break if up: if scanResult.up != True: scanResult.updateRecord(scanResult.ip, True) change = True if not self.stateChange or change: discovered.append({ "ip": scanResult.ip, "up": True, "scanName": scanResult.scanName }) else: if scanResult.up != False: scanResult.updateRecord(scanResult.ip, False) change = True if not self.stateChange or change: discovered.append({ "ip": scanResult.ip, "up": False, "scanName": scanResult.scanName }) if not change: scanResult.lastScan = int(time.time()) scanResult.update(["lastScan"]) if len(discovered) > 0: return {"result": True, "rc": 0, "discovered": discovered} else: return {"result": False, "rc": 404}
def networkScansResults(): scansResults = inga._inga().getAsClass(api.g.sessionData,query={ "up" : True },fields=["scanName","ip","up","lastScan","ports"]) nodesDict = {} edgesDict = {} for scansResult in scansResults: if scansResult.scanName not in nodesDict: nodesDict[scansResult.scanName] = { "id" : scansResult.scanName, "label" : scansResult.scanName, "shape" : "dot", "value" : 1, "color" : { "background" : "#C72F1E", "border" : "#C72F1E" , "highlight" : { "background" : "#000", "border" : "#FFF" } } } if scansResult.ip not in nodesDict: nodesDict[scansResult.ip] = { "id" : scansResult.ip, "label" : scansResult.ip, "shape" : "image", "image" : "/static/img/computer.svg", "value" : 1, "color" : { "background" : "#C72F1E", "border" : "#C72F1E" , "highlight" : { "background" : "#000", "border" : "#FFF" } } } else: nodesDict[scansResult.ip]["value"] += 1 key = "{0}-{1}".format(scansResult.scanName,scansResult.ip) if key not in edgesDict: edgesDict[key] = { "id" : key, "from" : scansResult.scanName, "to" : scansResult.ip } nodes = [ x for x in nodesDict.values() ] edges = [ x for x in edgesDict.values() ] options = { "interaction": { "tooltipDelay": 200, "hideEdgesOnDrag": True, "hideEdgesOnZoom": True, }, "layout": { "improvedLayout": False }, "physics": { "enabled": True, "timestep": 1, "stabilization": False, "barnesHut" : { "springConstant" : 0.001 } }, "nodes": { "shape": "dot", "color": { "background": "#4090c9", "highlight": { "background": "#000", "border": "#FFF" } }, "font": { "size": 10, "face": "Tahoma", "color": "#bfbfbf" } }, "edges": { "width": 1, "selectionWidth": 1, "color": { "color": "#ffffff2f", "highlight": "#FFF", }, "smooth": { "type": "continuous", } } } return { "nodes" : nodes, "edges" : edges, "options" : options }, 200
def getScan(scanName): scansResults = inga._inga().query(api.g.sessionData,query={ "scanName" : scanName, "up" : True },fields=["scanName","ip","up","lastScan","ports"])["results"] return render_template("ingaScan.html",CSRF=jimi.api.g.sessionData["CSRF"],scanResults=ui.dictTable(scansResults))