def asset_extraction(scanner): for sid in scanner.sitelist.keys(): debug.printd('requesting devices for site %s (%s)' % \ (scanner.sitelist[sid]['id'], scanner.sitelist[sid]['name'])) devdata = scanner.conn.site_device_listing(sid) root = ET.fromstring(devdata) for s in root: if s.tag != 'SiteDevices': continue siteid = s.attrib['site-id'] devlist = [] for d in s: newdev = {} newdev['id'] = int(d.attrib['id']) newdev['address'] = d.attrib['address'] newdev['vulns'] = [] scanner.sitelist[sid]['assets'].append(newdev) add_asset_properties(scanner) debug.printd('requesting asset groups') grpdata = scanner.conn.asset_group_listing() root = ET.fromstring(grpdata) for g in root: if g.tag != 'AssetGroupSummary': continue newgrp = {} newgrp['name'] = g.attrib['name'] newgrp['id'] = g.attrib['id'] scanner.grouplist[int(g.attrib['id'])] = newgrp
def serviceapi_vulnlist(vlist): if not serviceapi_enabled: return vlist oplist = [] for x in vlist: oplist.append(json.loads(x)) debug.printd( 'preparing query for serviceapi service lookup (vulnerabilities)') s = pyservicelib.Search() havehosts = [] for x in oplist: hn = x['asset']['hostname'] if len(hn) == 0: continue if hn in havehosts: continue s.add_host(hn, confidence=90) havehosts.append(hn) s.execute() for x in oplist: if len(x['asset']['hostname']) == 0: continue sres = s.result_host(x['asset']['hostname']) if sres == None: continue x['service'] = sres return [json.dumps(x) for x in oplist]
def spool_scan_results(scanner, scanid, target): retvuln = [] squery = ''' SELECT da.asset_id, da.ip_address, da.host_name, da.mac_address, dv.title AS vulnerability, round(dv.cvss_score::numeric, 2) AS cvss_score FROM fact_asset_scan_vulnerability_finding favf JOIN dim_asset da USING (asset_id) JOIN dim_vulnerability dv USING (vulnerability_id) WHERE favf.scan_id = %s AND da.ip_address = '%s' ''' % (scanid, target) debug.printd('requesting vulnerability results...') buf = nexadhoc.nexpose_adhoc(scanner, squery, [spoolconf.siteid,], \ scan_ids=[scanid,], api_version='1.3.2') reader = csv.reader(StringIO.StringIO(buf)) for i in reader: if len(i) == 0: continue if i[0] == 'asset_id': continue v = {} v['assetid'] = int(i[0]) v['ipaddress'] = i[1] v['hostname'] = i[2] v['macaddress'] = i[3] v['title'] = i[4] v['cvss'] = float(i[5]) retvuln.append(v) return retvuln
def serviceapi_complist(clist): if not serviceapi_enabled: return clist oplist = [] for x in clist: oplist.append(json.loads(x)) debug.printd('preparing query for serviceapi service lookup (compliance)') s = pyservicelib.Search() havehosts = [] for x in oplist: # XXX As this data originates from MIG we should always have a valid # hostname field here, but check anyway. hn = x['target'] if len(hn) == 0: continue if hn in havehosts: continue s.add_host(hn, confidence=90) havehosts.append(hn) s.execute() for x in oplist: if len(x['target']) == 0: continue sres = s.result_host(x['target']) if sres == None: continue x['service'] = sres return [json.dumps(x) for x in oplist]
def load_vulnauto_list(path): debug.printd('reading automation data from %s' % path) cp = ConfigParser.SafeConfigParser() cp.read(path) for s in cp.sections(): n = VulnAutoEntry(s) for k, v in cp.items(s): if k == 'mincvss': n.mincvss = float(v) pass elif k == 'ipmatch': if v != '': n.add_match(v) elif k == 'namematch': if v != '': for i in v.split(): if i == '#AUTOADD': continue n.add_namematch(i) elif k == 'name': n.title = v elif k == 'description': n.description = v else: sys.stderr.write('vulnauto option %s not available under ' \ '%s\n' % (k, s)) sys.exit(1) vulnautolist.append(n)
def calculate_compliance(uid): debug.printd('calculating compliance for %s' % uid) ret = dbconn.compliance_values(uid) failvid = None failage = 0 max_cvss = 0 for level in ComplianceLevels.ORDERING: for val in ret: vid = val[0] cvss = val[1] age = val[2] if cvss >= ComplianceLevels.FLOOR[level] and \ age > ComplianceLevels.LEVELS[level]: # Compliance failure, note the vulnerability that caused the # failure that has the highest CVSS base score if failvid == None or max_cvss < cvss: failvid = vid max_cvss = cvss failage = age if failvid != None: break failflag = False if failvid != None: debug.printd('asset fails compliance due to vid %d ' '(cvss=%f, age=%d)' % (failvid, max_cvss, failage)) failflag = True dbconn.compliance_update(uid, failflag, failvid)
def spool_scan_results(scanner, scanid, target): retvuln = [] squery = ''' SELECT da.asset_id, da.ip_address, da.host_name, da.mac_address, dv.title AS vulnerability, round(dv.cvss_score::numeric, 2) AS cvss_score FROM fact_asset_scan_vulnerability_finding favf JOIN dim_asset da USING (asset_id) JOIN dim_vulnerability dv USING (vulnerability_id) WHERE favf.scan_id = %s AND da.ip_address = '%s' ''' % (scanid, target) debug.printd('requesting vulnerability results...') buf = nexadhoc.nexpose_adhoc(scanner, squery, [spoolconf.siteid,], \ scan_ids=[scanid,], api_version='1.3.2') reader = csv.reader(StringIO.StringIO(buf)) for i in reader: if len(i) == 0: continue if i[0] == 'asset_id': continue v = {} v['assetid'] = int(i[0]) v['ipaddress'] = i[1] v['hostname'] = i[2] v['macaddress'] = i[3] v['title'] = i[4] v['cvss'] = float(i[5]) retvuln.append(v) return retvuln
def serviceapi_vulnlist(vlist): if not serviceapi_enabled: return vlist oplist = [] for x in vlist: oplist.append(json.loads(x)) debug.printd('preparing query for serviceapi service lookup (vulnerabilities)') s = pyservicelib.Search() havehosts = [] for x in oplist: hn = x['asset']['hostname'] if len(hn) == 0: continue if hn in havehosts: continue s.add_host(hn, confidence=90) havehosts.append(hn) s.execute() for x in oplist: if len(x['asset']['hostname']) == 0: continue sres = s.result_host(x['asset']['hostname']) if sres == None: continue x['service'] = sres return [json.dumps(x) for x in oplist]
def serviceapi_complist(clist): if not serviceapi_enabled: return clist oplist = [] for x in clist: oplist.append(json.loads(x)) debug.printd('preparing query for serviceapi service lookup (compliance)') s = pyservicelib.Search() havehosts = [] for x in oplist: # XXX As this data originates from MIG we should always have a valid # hostname field here, but check anyway. hn = x['target'] if len(hn) == 0: continue if hn in havehosts: continue s.add_host(hn, confidence=90) havehosts.append(hn) s.execute() for x in oplist: if len(x['target']) == 0: continue sres = s.result_host(x['target']) if sres == None: continue x['service'] = sres return [json.dumps(x) for x in oplist]
def vuln_get_age_data(scanner): squery = ''' SELECT asset_id, vulnerability_id, age_in_days FROM fact_asset_vulnerability_age ''' ret = {} debug.printd('requesting vulnerability age information') sites = scanner.sitelist.keys() if len(sites) == 0: return vulndata = scanner.conn.adhoc_report(squery, sites, api_version='1.3.2') reader = csv.reader(StringIO.StringIO(vulndata)) for i in reader: if len(i) == 0: continue if i[0] == 'asset_id': continue assetid = int(i[0]) vid = int(i[1]) age = float(i[2]) if assetid not in ret: ret[assetid] = {} if vid not in ret[assetid]: ret[assetid][vid] = age else: if age > ret[assetid][vid]: ret[assetid][vid] = age return ret
def resolve_workflow_for_asset(self, assetid): c = self._conn.cursor() debug.printd('resolving all known issues for expired asset id %d' % assetid) c.execute('''UPDATE workflow SET status = ? WHERE vid IN (SELECT id FROM assetvulns WHERE aid = ?)''', (vuln.WorkflowElement.STATUS_RESOLVED, assetid)) self._conn.commit()
def button_clicked(self): self.selected_button = self.buttons.index(self.sender()) printd(f"Button {self.selected_button} was clicked") #debug self.selected.setText(f"SELECTED {self.selected_button}") for i, byte in enumerate(self.guibytes): self.byte.setText(self.settings[self.selected_button][i])
def escalate_hints(escdir, scanner, hintsflag, whereclause): if not hintsflag: return debug.printd('extracting asset hint data from database') hintblock = hints_block(scanner, whereclause) hlist = [] for x in hintblock: hlist.append(json.dumps(hintblock[x])) write_hint_escalations(hlist, escdir)
def serviceapi_init(apihost, apicert): global serviceapi_enabled debug.printd('initializing integration with service api') if apicert == None: pyservicelib.config.sslverify = False else: pyservicelib.config.sslverify = apicert pyservicelib.config.apihost = apihost serviceapi_enabled = True
def spool_scan_request(scanner, request): spool_extension_sw(request, '.new', '.exec') debug.printd('requesting scan for %s' % request['target']) scanid = spool_scan_address(scanner, request['target']) debug.printd('running as scanid %s' % scanid) request['scanid'] = scanid fd = open(request['path'], 'w') json.dump(request, fd) fd.close()
def escalate_hints(escdir, scanner, hintsflag, whereclause): if not hintsflag: return debug.printd('extracting asset hint data from database') hintblock = hints_block(scanner, whereclause) hlist = [] for x in hintblock: hlist.append(json.dumps(hintblock[x])) write_hint_escalations(hlist, escdir)
def spool_scan_request(scanner, request): spool_extension_sw(request, '.new', '.exec') debug.printd('requesting scan for %s' % request['target']) scanid = spool_scan_address(scanner, request['target']) debug.printd('running as scanid %s' % scanid) request['scanid'] = scanid fd = open(request['path'], 'w') json.dump(request, fd) fd.close()
def serviceapi_init(apihost, apicert): global serviceapi_enabled debug.printd('initializing integration with service api') if apicert == None: pyservicelib.config.sslverify = False else: pyservicelib.config.sslverify = apicert pyservicelib.config.apihost = apihost serviceapi_enabled = True
def remove_asset(self, assetid): c = self._conn.cursor() debug.printd('removing database asset id %d' % assetid) c.execute('''DELETE FROM workflow WHERE vid IN (SELECT id FROM assetvulns WHERE aid = %d)''' % assetid) c.execute('''DELETE FROM assetvulns WHERE aid = %d''' % assetid) c.execute('''DELETE FROM compliance WHERE aid = %d''' % assetid) c.execute('''DELETE FROM assets WHERE id = %d''' % assetid) self._conn.commit()
def write_hint_escalations(hlist, escdir): fname = 'hints-%d-%d.dat' % (int(calendar.timegm(time.gmtime())), os.getpid()) outfile = os.path.join(escdir, fname) tmpoutfile = outfile + '.tmp' debug.printd('writing hint escalations to %s' % outfile) fd = open(tmpoutfile, 'w') cPickle.dump(hlist, fd) fd.close() os.rename(tmpoutfile, outfile)
def write_compliance_escalations(clist, escdir): fname = 'compliance-%d-%d.dat' % (int(calendar.timegm( time.gmtime())), os.getpid()) outfile = os.path.join(escdir, fname) tmpoutfile = outfile + '.tmp' debug.printd('writing compliance escalations to %s' % outfile) fd = open(tmpoutfile, 'w') cPickle.dump(clist, fd) fd.close() os.rename(tmpoutfile, outfile)
def write_vuln_escalations(vlist, escdir): fname = 'vulns-%d-%d.dat' % (int(calendar.timegm( time.gmtime())), os.getpid()) outfile = os.path.join(escdir, fname) tmpoutfile = outfile + '.tmp' debug.printd('writing vulnerabilities escalations to %s' % outfile) fd = open(tmpoutfile, 'w') cPickle.dump(vlist, fd) fd.close() os.rename(tmpoutfile, outfile)
def load_vulnauto(dirpath, vmdbconn): global dbconn debug.printd('reading vulnerability automation data...') dbconn = vmdbconn dirlist = os.listdir(dirpath) for i in dirlist: # Ignore templates if '.tmpl' in i: continue load_vulnauto_list(os.path.join(dirpath, i))
def load_exemption_list(path): debug.printd('reading exemptions from %s' % path) cp = ConfigParser.SafeConfigParser() cp.read(path) for s in cp.sections(): # XXX Need to validate format and warn on syntax issues if '/' in s: exemptlist_nets.append(s) else: exemptlist_hosts.append(s)
def send_indicators(scanner): if not serviceapi_enabled: return debug.printd('submitting indicators for all known assets...') ind = pyservicelib.Indicators() for s in scanner.sitelist.keys(): for a in scanner.sitelist[s]['assets']: # If we dont have a hostname, don't bother sending anything if a['hostname'] == '': continue ind.add_host(a['hostname'], 'vuln', 'nexpose', a['credsok']) ind.execute()
def asset_unique_id(address, mac, hostname, aid): if mac == '': u_mac = 'NA' else: u_mac = mac if hostname == '': u_hostname = 'NA' else: u_hostname = hostname ret = '0|%s|%s|%s|%s' % (aid, address, u_hostname, u_mac) debug.printd('using identifier %s' % ret) return ret
def site_extraction(scanner): debug.printd('requesting site information') sitedata = scanner.conn.site_listing() root = ET.fromstring(sitedata) for s in root: siteinfo = {} siteinfo['name'] = s.attrib['name'] siteinfo['id'] = s.attrib['id'] siteinfo['assets'] = [] scanner.sitelist[siteinfo['id']] = siteinfo debug.printd('read %d sites' % len(scanner.sitelist))
def dataset_compstat(vmd): debug.printd('summarizing compliance statistics...') vmd.current_compstat['passfailcount'] = \ compliance_count(vmd.current_compliance) vmd.current_compstat['impactsum'] = \ compliance_impactsum(vmd.current_compliance) for i in vmd.previous_compliance: newval = {} newval['passfailcount'] = compliance_count(i) newval['impactsum'] = compliance_impactsum(i) vmd.previous_compstat.append(newval)
def send_indicators(scanner): if not serviceapi_enabled: return debug.printd('submitting indicators for all known assets...') ind = pyservicelib.Indicators() for s in scanner.sitelist.keys(): for a in scanner.sitelist[s]['assets']: # If we dont have a hostname, don't bother sending anything if a['hostname'] == '': continue ind.add_host(a['hostname'], 'vuln', 'nexpose', a['credsok']) ind.execute()
def run_rgb_engine(self): printd("START RGB ENGINE") while self.__running: if(self.midi.input.poll()): data = self.midi.input.read(1) self.query.append(data) #printd(data)#debug #printd(type(data[0][0][0])) printd("STOP RGB ENGINE")
def nexpose_adhoc(scanner, squery, sites, api_version=None, cache_key=None, scan_ids=[], device_ids=[]): if cache_key == None: cache_key = get_cache_key(squery) cachefn = './adhoc.' + cache_key if adhoc_cache: debug.printd('using adhoc cache %s' % cachefn) flag, data = get_cache(cachefn) if flag: debug.printd('cache hit, returning data') return data debug.printd('cache not found, will populate this round') ret = None if api_version != None: ret = scanner.conn.adhoc_report(squery, sites, api_version=api_version, scan_ids=scan_ids, device_ids=device_ids) else: ret = scanner.conn.adhoc_report(squery, sites, scan_ids=scan_ids, device_ids=device_ids) if adhoc_cache: debug.printd('writing cache to %s' % cachefn) write_cache(cachefn, ret) return ret
def site_update_from_files(scanner, sid, pathlist): tmpfile = tempfile.mkstemp() tmpfilefd = os.fdopen(tmpfile[0], 'w') for i in pathlist: try: fd = open(i, 'r') except IOError: debug.printd('cannot read %s, skipping site' % i) os.remove(tmpfile[1]) return tmpfilefd.write(fd.read()) fd.close() tmpfilefd.close() site_update_from_file(scanner, sid, tmpfile[1]) os.remove(tmpfile[1])
def escalate_vulns(escdir, escalate_vulns, escalate_compliance): ret = dbconn.asset_list() debug.printd('processing %d assets' % len(ret)) vlist = [] for i in ret: wfes = dbconn.get_workflow(i) for w in wfes: # Only escalate things that haven't been handled yet if w.status != WorkflowElement.STATUS_NONE and \ w.status != WorkflowElement.STATUS_RESOLVED: continue if w.status == WorkflowElement.STATUS_NONE: w.status = WorkflowElement.STATUS_ESCALATED elif w.status == WorkflowElement.STATUS_RESOLVED: w.status = WorkflowElement.STATUS_CLOSED # Create JSON event from the element jv = vmjson.wf_to_json(w) vlist.append(jv) # Mark this workflow element as handled now dbconn.workflow_handled(w.workflow_id, w.status) if len(vlist) > 0: if escalate_vulns: write_vuln_escalations(vlist, escdir) clist = [] # Do the same thing for compliance items for i in ret: ce = dbconn.get_compliance(i) # get_compliance returning None means the system passed compliance # checks, we still want to create an event though. if ce == None: target = dbconn.aid_to_host(i) else: target = ce.failvuln.hostname jc = vmjson.ce_to_json(ce, target) clist.append(jc) if len(clist) > 0: if escalate_compliance: write_compliance_escalations(clist, escdir)
def resolve_vulnerability(self, vidlist, dbassetid): c = self._conn.cursor() c.execute('''SELECT vulns.nxvid, assetvulns.id FROM vulns JOIN assetvulns ON vulns.id = assetvulns.vid WHERE assetvulns.aid = ?''', (dbassetid,)) rows = c.fetchall() for i in rows: if i[0] in vidlist: continue debug.printd('marking vulnerability %d as resolved' % i[1]) # We previously knew about the vulnerability on the device # and it's not there anymore, mark it as resolved c.execute('''UPDATE workflow SET status = ? WHERE vid = ?''', (vuln.WorkflowElement.STATUS_RESOLVED, i[1]))
def workflow_check_reset(self, vid): # This function is called by add_vulnerability to handle a case where # a vulnerability reappears on an asset after it has been resolved. # We basically check the vid to see if it is resolved/closed, if it # is reset it to new. c = self._conn.cursor() c.execute('''SELECT status FROM workflow WHERE vid = ?''', (vid,)) rows = c.fetchall() if len(rows) == 0: return sts = rows[0][0] if sts == vuln.WorkflowElement.STATUS_RESOLVED or \ sts == vuln.WorkflowElement.STATUS_CLOSED: c.execute('''UPDATE workflow SET status = 0 WHERE vid = ?''', (vid,)) debug.printd('reset status on vid %d' % vid)
def asset_search_and_update(self, uid, aid, address, mac, hostname): # See if we had any previous instance of this MAC address and # hostname, if so update the asset with new value if mac == '': return c = self._conn.cursor() c.execute('''SELECT id, uid FROM assets WHERE mac = ? AND hostname = ?''', (mac, hostname)) rows = c.fetchall() if len(rows) == 0: return if rows[0][1] == uid: return debug.printd('updating information for asset %s' % uid) debug.printd('was: %s now: %s' % (rows[0][1], uid)) c.execute('''UPDATE assets SET uid = ?, ip = ?, hostname = ?, nxaid = ? WHERE id = ?''', (uid, address, hostname, aid, rows[0][0]))
def reptest(scanner): squery = ''' SELECT da.ip_address, da.host_name, os.name, critical_vulnerabilities, severe_vulnerabilities, exploits, riskscore, aggregated_credential_status_description FROM fact_asset JOIN dim_aggregated_credential_status USING(aggregated_credential_status_id) JOIN dim_asset da USING(asset_id) JOIN dim_operating_system os USING(operating_system_id) ''' debug.printd('adhoc report test') sites = scanner.sitelist.keys() if len(sites) == 0: return ret = scanner.conn.adhoc_report(squery, sites, api_version='1.3.2') print ret sys.exit(0)
def add_asset(self, uid, aid, address, mac, hostname): c = self._conn.cursor() c.execute('''SELECT id FROM assets WHERE uid="%s"''' % uid) rows = c.fetchall() if len(rows) == 0: # Before we add the asset, make sure this isn't a duplicate being # reported by the scanner if len(self.asset_duplicate_resolver(uid)) != 0: debug.printd('aid %d looks like a duplicate, ignoring' % aid) return None c.execute('''INSERT INTO assets VALUES (NULL, "%s", %d, "%s", "%s", "%s")''' % (uid, aid, address, hostname, mac)) ret = c.lastrowid # We also want a compliance tracking item for each asset c.execute('''INSERT INTO compliance VALUES (NULL, %d, 0, NULL, 0, 0)''' % ret) self._conn.commit() return ret else: return rows[0][0]
def add_asset(self, uid, aid, address, mac, hostname): c = self._conn.cursor() c.execute('''SELECT id FROM assets WHERE uid = ?''', (uid,)) rows = c.fetchall() if len(rows) == 0: # Before we add the asset, make sure this isn't a duplicate being # reported by the scanner if len(self.asset_duplicate_resolver(uid)) != 0: debug.printd('aid %d looks like a duplicate, ignoring' % aid) return None c.execute('''INSERT INTO assets VALUES (NULL, ?, ?, ?, ?, ?)''', (uid, aid, address, hostname, mac)) ret = c.lastrowid # We also want a compliance tracking item for each asset c.execute('''INSERT INTO compliance VALUES (NULL, ?, 0, NULL, 0, 0)''', (ret,)) self._conn.commit() return ret else: return rows[0][0]
def spool_runner(path, scanner): global spoolconf sitedata = [] spoolconf = SpoolConfig(path) spooldata = load_spool(spoolconf.spooldir) # For any new targets, make sure the site configuration has this target # in scope. targetlist = [x['target'] for x in spooldata.new_requests] debug.printd('%d new requests' % len(spooldata.new_requests)) spool_update_site_config(scanner, targetlist) # For any new targets, initiate the scans spool_scan(scanner, spooldata.new_requests) # For any existing targets, check the status, collecting results # if available. debug.printd('%d in-flight requests' % len(spooldata.exec_requests)) spool_status(scanner, spooldata.exec_requests)
def send_rgb(self, button, rgb): #fill up with "0" button = str(button) while (len(button) < 2): button = "0" + button rgb = str(rgb) while (len(rgb) < 3): rgb = "0" + rgb #message to send to launchpad message = f"{button}.{rgb}" #transmit! self.send(message) self.connection.flushInput( ) #there is a bug, where read bytes remain in input buffer after this message is sent printd(f"sending message {message}") #debug
def mozdef_proc(escdir, mozdef_compliance_urls, mozdef_vuln_urls, mozdef_hint_urls): escfiles = os.listdir(escdir) escfiles = sorted(escfiles, key=lambda x: x.split('-')[1]) for i in escfiles: p = os.path.join(escdir, i) fd = open(p, 'r') events = cPickle.load(fd) fd.close() if 'vulns' in i: for x in mozdef_vuln_urls: debug.printd('writing to %s' % x) msg = mozdef.MozDefVulnerability(x) msg.set_fire_and_forget(False) for j in events: d = json.loads(j) msg.log = d msg.send() elif 'compliance' in i: for x in mozdef_compliance_urls: debug.printd('writing to %s' % x) msg = mozdef.MozDefCompliance(x) msg.set_fire_and_forget(False) for j in events: d = json.loads(j) msg.summary = 'vmintgr compliance item' msg.details = d msg.tags = ['vmintgr', 'compliance'] msg.send() elif 'hint' in i: for x in mozdef_hint_urls: debug.printd('writing to %s' % x) msg = mozdef.MozDefAssetHint(x) msg.set_fire_and_forget(False) for j in events: d = json.loads(j) msg.summary = d['summary'] msg.details = d['details'] msg.tags = d['tags'] msg.send() os.remove(p)
def spool_update_site_config(scanner, alist): if len(alist) == 0: return foundlist = {} for x in alist: foundlist[x] = False debug.printd('updating site configuration for site %s' % spoolconf.siteid) siteconf = scanner.conn.site_config(spoolconf.siteid) root = ET.fromstring(siteconf) siteentry = root.find('Site') if siteentry == None: raise Exception('no Site subelement in response') hostlist = siteentry.find('Hosts') if hostlist == None: raise Exception('no Hosts subelement in response') for s in hostlist: if s.tag != 'range': continue low = s.get('from') high = s.get('to') plist = [] if high != None: ipl = list(netaddr.iter_iprange(low, high)) plist = [str(x) for x in ipl] else: plist = [low,] for a in plist: if a in foundlist: foundlist[a] = True for i in foundlist: if foundlist[i]: debug.printd('site already has %s' % i) continue debug.printd('adding %s' % i) newsub = ET.SubElement(hostlist, 'range') newsub.set('from', i) scanner.conn.site_save((ET.tostring(siteentry),))
def spool_status_request(scanner, request): debug.printd('checking status of scan %s' % request['scanid']) resp = scanner.conn.scan_status(request['scanid']) response = ET.fromstring(resp) if response.tag != 'ScanStatusResponse' or \ response.get('success') != '1': raise Exception('scan status request failed') if response.get('status') != 'finished': debug.printd('scan %s not complete' % request['scanid']) return debug.printd('scan %s is complete' % request['scanid']) # Request the results scanresults = spool_scan_results(scanner, request['scanid'], \ request['target']) request = spool_extension_sw(request, '.exec', '.done') request['findings'] = scanresults fd = open(request['path'], 'w') json.dump(request, fd) fd.close()
def hints_block(scanner, whereclause): squery = ''' SELECT asset_id, da.ip_address, da.host_name, da.mac_address, dos.description as operating_system, dht.description, dos.cpe FROM dim_asset da JOIN dim_operating_system dos USING (operating_system_id) JOIN dim_host_type dht USING (host_type_id) %s ''' % whereclause buf = nexadhoc.nexpose_adhoc(scanner, squery, [], api_version='1.3.2') ret = {} reader = csv.reader(StringIO.StringIO(buf)) for i in reader: if len(i) == 0: continue if i[0] == 'asset_id': continue newent = {} newent['summary'] = 'vmintgr asset hint' newent['tags'] = ['vmintgr', 'asset'] newdet = {} newdet['nexassetid'] = i[0] newdet['source'] = vmjson.get_sourcename() newdet['ipv4'] = [] newdet['ipv4'].append(i[1]) newdet['ipv6'] = [] if len(i[2]) > 0: newdet['hostname'] = i[2] newdet['macaddress'] = [] if len(i[3]) > 0: newdet['macaddress'].append(i[3]) if len(i[4]) > 0 and i[4] != 'Unknown': newdet['ident'] = i[4] if len(i[5]) > 0 and i[5] != 'Unknown': newdet['hosttype'] = i[5] if len(i[6]) > 0 and i[6] != 'Unknown': newdet['cpe'] = i[6] newent['details'] = newdet ret[i[0]] = newent debug.printd('extracting asset ip aliases') squery = ''' SELECT asset_id, ip_address, type FROM dim_asset_ip_address ''' buf = nexadhoc.nexpose_adhoc(scanner, squery, [], api_version='1.3.2') reader = csv.reader(StringIO.StringIO(buf)) for i in reader: if len(i) == 0: continue if i[0] == 'asset_id': continue if i[0] not in ret: continue t = i[2] if t == 'IPv4': if i[1] not in ret[i[0]]['details']['ipv4']: debug.printd('adding another ip address for %s' % i[0]) ret[i[0]]['details']['ipv4'].append(i[1]) elif t == 'IPv6': if i[1] not in ret[i[0]]['details']['ipv6']: debug.printd('adding another ip address for %s' % i[0]) ret[i[0]]['details']['ipv6'].append(i[1]) debug.printd('extracting asset mac aliases') squery = ''' SELECT asset_id, mac_address FROM dim_asset_mac_address ''' buf = nexadhoc.nexpose_adhoc(scanner, squery, [], api_version='1.3.2') reader = csv.reader(StringIO.StringIO(buf)) for i in reader: if len(i) == 0: continue if i[0] == 'asset_id': continue if i[0] not in ret: continue if i[1] not in ret[i[0]]['details']['macaddress']: debug.printd('adding another mac address for %s' % i[0]) ret[i[0]]['details']['macaddress'].append(i[1]) debug.printd('extracting asset software') squery = ''' SELECT da.asset_id, ds.name, ds.version FROM dim_asset da JOIN dim_asset_software USING (asset_id) JOIN dim_software ds USING (software_id) ''' buf = nexadhoc.nexpose_adhoc(scanner, squery, [], api_version='1.3.2') reader = csv.reader(StringIO.StringIO(buf)) for i in reader: if len(i) == 0: continue if i[0] == 'asset_id': continue if i[0] not in ret: continue if 'software' not in ret[i[0]]['details']: ret[i[0]]['details']['software'] = [] ret[i[0]]['details']['software'].append('%s-%s' % \ (i[1], i[2])) return ret