def customer_xml(): """ Generates an XML file suitable for Customer usage """ from lxml import etree location_attribute = '{%s}noNameSpaceSchemaLocation' % "http://www.w3.org/2001/XMLSchema-instance" kvasir_results_xml = etree.Element('KvasirResults', attrib={ location_attribute: 'kvasir.xsd', }) summary_xml = etree.SubElement(kvasir_results_xml, 'summary') customer = etree.SubElement(summary_xml, 'customer') customer.text = settings.customer or 'CUSTOMER NAME' assessment = etree.SubElement(summary_xml, 'assessment') assessment.set('type', settings.assessment_type) start_date = etree.SubElement(assessment, 'start-date') start_date.text = settings.start_date or 'START DATE' end_date = etree.SubElement(assessment, 'end-date') end_date.text = settings.end_date or 'END DATE' hosts_xml = etree.SubElement(kvasir_results_xml, 'hosts') os_xml = etree.SubElement(kvasir_results_xml, 'os_records') vulns_xml = etree.SubElement(kvasir_results_xml, 'vulns') # this is a little hack to ensure a record is either blank or None # use it as "if variable not in notin:" notin = [None, ''] unknown_cpeid_counter = 0 # go through each host, adding the os, services and vulns accordingly query = create_hostfilter_query(session.hostfilter) for host_rec in db(query).select(): host_xml = etree.SubElement(hosts_xml, 'host') host_xml.set('ipaddr', host_rec.f_ipaddr) host_xml.set('assetgroup', host_rec.f_asset_group) if host_rec.f_macaddr: host_xml.set('macaddr', host_rec.f_macaddr) if host_rec.f_hostname: host_xml.set('hostname', host_rec.f_hostname.decode('utf-8')) if host_rec.f_netbios_name: host_xml.set('netbios', host_rec.f_netbios_name.decode('utf-8')) # build the os information using the highest certainty record highest = (0, None) for os_rec in db(db.t_host_os_refs.f_hosts_id == host_rec.id).select(): if os_rec.f_certainty > highest[0]: highest = (os_rec.f_certainty, os_rec) if highest[0] > 0: # add os element to the host record = highest[1] os = etree.SubElement(host_xml, 'os') os.set('certainty', str(highest[0])) if record.f_class not in notin: os.set('class', record.f_class) if record.f_family not in notin: os.set('family', record.f_family) # since some os records may not have a cpe id we'll mask them with # using their title, replacing spaces with underscores t_os_rec = db.t_os[record.f_os_id] if t_os_rec.f_cpename in notin: cpeid = t_os_rec.f_title.replace(' ', '_') else: cpeid = t_os_rec.f_cpename os.set('id', cpeid) # if the id isn't in os_records, add it if len(os_xml.findall('.//os[@id="%s"]' % (os.get('id', None)))) < 1: os_info_xml = etree.SubElement(os_xml, 'os') os_rec = db.t_os[highest[1].f_os_id] os_info_xml.set('id', cpeid) os_info_xml.set('title', os_rec.f_title) if os_rec.f_vendor not in notin: vendor = etree.SubElement(os_info_xml, 'vendor') vendor.text = os_rec.f_vendor if os_rec.f_product not in notin: product = etree.SubElement(os_info_xml, 'product') product.text = os_rec.f_product if os_rec.f_version not in notin: version = etree.SubElement(os_info_xml, 'version') version.text = os_rec.f_version if os_rec.f_update not in notin: update = etree.SubElement(os_info_xml, 'update') update.text = os_rec.f_update if os_rec.f_edition not in notin: edition = etree.SubElement(os_info_xml, 'edition') edition.text = os_rec.f_edition if os_rec.f_language not in notin: language = etree.SubElement(os_info_xml, 'language') language.text = os_rec.f_language # snmp strings snmp_recs = db(db.t_snmp.f_hosts_id == host_rec.id).select() if len(snmp_recs) > 0: snmp_top_xml = etree.SubElement(hosts_xml, 'snmps') for record in snmp_recs: snmp_xml = etree.SubElement(snmp_top_xml, 'snmp') if record.f_community not in notin: snmp_xml.set('community', record.f_community.decode('utf-8')) snmp_xml.set('version', record.f_version) snmp_xml.set('access', record.f_access) # netbios information netb_record = db( db.t_netbios.f_hosts_id == host_rec.id).select().first() or None if netb_record: netbios_xml = etree.SubElement(hosts_xml, 'netbios') if netb_record.f_type not in notin: netbios_xml.set('type', netb_record.f_type) if netb_record.f_domain not in notin: netbios_xml.set('domain', netb_record.f_domain.decode('utf-8')) if netb_record.f_lockout_limit not in notin: netbios_xml.set('lockout_limit', str(netb_record.f_lockout_limit)) if netb_record.f_lockout_duration not in notin: netbios_xml.set('lockout_duration', str(netb_record.f_lockout_duration)) if netb_record.f_advertised_names is not None: adv_names_xml = etree.SubElement(netbios_xml, 'advertised_names') for name in netb_record.f_advertised_names: name_xml = etree.SubElement(adv_names_xml, 'name') name.text = name.decode('utf-8') # build the services and vulnerabilities services_xml = etree.SubElement(host_xml, 'services') for svc_rec in db(db.t_services.f_hosts_id == host_rec.id).select(): service_xml = etree.SubElement(services_xml, 'service') service_xml.set('proto', svc_rec.f_proto) service_xml.set('number', svc_rec.f_number) if svc_rec.f_name not in notin: name = etree.SubElement(service_xml, 'name') name.text = svc_rec.f_name.decode('utf-8') if svc_rec.f_banner not in notin: banner = etree.SubElement(service_xml, 'banner') banner.text = svc_rec.f_banner.decode('utf-8') # service configuration records svc_info_recs = db( db.t_service_info.f_services_id == svc_rec.id).select() if len(svc_info_recs) > 0: config_xml = etree.SubElement(service_xml, 'configuration') for info_rec in svc_info_recs: rec_xml = etree.SubElement(config_xml, 'config') if info_rec.f_name not in notin: rec_xml.set('name', info_rec.f_name) if info_rec.f_text not in notin: rec_xml.text = info_rec.f_text.decode('utf-8') # vulnerabilities svc_vuln_recs = db( db.t_service_vulns.f_services_id == svc_rec.id).select() if len(svc_vuln_recs) > 0: svc_vulns_xml = etree.SubElement(service_xml, 'vulns') for vuln_rec in svc_vuln_recs: vuln_xml = etree.SubElement(svc_vulns_xml, 'vuln') vuln_xml.set('status', vuln_rec.f_status) vuln_xml.set( 'id', db.t_vulndata[vuln_rec.f_vulndata_id].f_vulnid) proof = etree.SubElement(vuln_xml, 'proof') proof.text = etree.CDATA( unicode(MARKMIN(vuln_rec.f_proof).xml(), 'utf-8')) # search for the nexpose id in vulns_xml if len( vuln_xml.findall('.//vuln[@id="%s"]' % vuln_xml.get('id', None))) < 1: new_vuln_xml = etree.SubElement(vulns_xml, 'vuln') vulndata = db.t_vulndata[vuln_rec.f_vulndata_id] new_vuln_xml.set('id', vulndata.f_vulnid) new_vuln_xml.set('title', vulndata.f_title) new_vuln_xml.set('severity', str(vulndata.f_severity)) new_vuln_xml.set('pci_sev', str(vulndata.f_pci_sev)) new_vuln_xml.set('cvss_score', str(vulndata.f_cvss_score)) new_vuln_xml.set('cvss_metric', cvss_metrics(vulndata)) description = etree.SubElement(new_vuln_xml, 'description') description.text = etree.CDATA( unicode( MARKMIN(vulndata.f_description).xml(), 'utf-8')) solution = etree.SubElement(new_vuln_xml, 'solution') solution.text = etree.CDATA( unicode( MARKMIN(vulndata.f_solution).xml(), 'utf-8')) # find vulnerability references and add them vuln_refs = db(db.t_vuln_references.f_vulndata_id == vulndata.id).select() if len(vuln_refs) > 0: refs_xml = etree.SubElement( new_vuln_xml, 'references') for ref_rec in vuln_refs: record = db.t_vuln_refs[ref_rec.f_vuln_ref_id] ref_xml = etree.SubElement( refs_xml, 'reference') ref_xml.set('source', record.f_source) ref_xml.text = record.f_text.decode('utf-8') # accounts accounts = db(db.t_accounts.f_services_id == svc_rec.id).select() if len(accounts) > 0: accounts_xml = etree.SubElement(service_xml, 'accounts') for acct_rec in accounts: acct_xml = etree.SubElement(accounts_xml, 'account') if acct_rec.f_username not in notin: elem = etree.SubElement(acct_xml, 'username') elem.text = acct_rec.f_username.decode('utf-8') if acct_rec.f_fullname not in notin: elem = etree.SubElement(acct_xml, 'fullname') elem.text = acct_rec.f_fullname.decode('utf-8') if acct_rec.f_password not in notin: elem = etree.SubElement(acct_xml, 'password') elem.text = acct_rec.f_password.decode('utf-8') if acct_rec.f_hash1 not in notin: elem = etree.SubElement(acct_xml, 'hash1') elem.text = acct_rec.f_hash1 if acct_rec.f_hash1_type not in notin: elem = etree.SubElement(acct_xml, 'hash1_type') elem.text = acct_rec.f_hash1_type if acct_rec.f_hash2 not in notin: elem = etree.SubElement(acct_xml, 'hash2') elem.text = acct_rec.f_hash2 if acct_rec.f_hash2_type not in notin: elem = etree.SubElement(acct_xml, 'hash2_type') elem.text = acct_rec.f_hash2_type if acct_rec.f_uid not in notin: elem = etree.SubElement(acct_xml, 'uid') elem.text = acct_rec.f_uid if acct_rec.f_gid not in notin: elem = etree.SubElement(acct_xml, 'gid') elem.text = acct_rec.f_gid if acct_rec.f_level not in notin: elem = etree.SubElement(acct_xml, 'level') elem.text = acct_rec.f_level if acct_rec.f_domain not in notin: elem = etree.SubElement(acct_xml, 'domain') elem.text = acct_rec.f_domain.decode('utf-8') if acct_rec.f_description not in notin: elem = etree.SubElement(acct_xml, 'description') elem.text = acct_rec.f_description.decode('utf-8') result = etree.tostring(kvasir_results_xml, pretty_print=True, encoding=unicode) return result
def vulninfo_by_vulnid(): """ Returns the vulnerablilty details """ if request.args(0) is None: redirect(URL('default', 'error', vars={'msg': T('No Vulnerability ID sent')})) record = db(db.t_vulndata.f_vulnid==request.args(0)).select().first() if record is not None: # grab vuln references and format the table response.title = "%s :: Vulnerability Popup :: %s" % (settings.title, record.f_vulnid) #cvss_metrics = "AV:%s/AC:%s/Au:%s/C:%s/I:%s/A:%s" % (record.f_cvss_av, # record.f_cvss_ac, # record.f_cvss_au, # record.f_cvss_c, # record.f_cvss_i, # record.f_cvss_a) vulninfo = record cvssmetrics = cvss_metrics(record) refs = LOAD(request.controller, 'vuln_refs_by_vulnid', args=[record.id], ajax=True) exploits = LOAD(request.controller, 'vuln_exploits_by_vulnid', args=[record.id], ajax=True) # TODO: Add hosts with vulnerability -- include service info (proto/port) and # ability to delete vuln from service query = db.t_service_vulns.f_vulndata_id == record.id svc_vulns = db(query).select(db.t_service_vulns.f_services_id, db.t_service_vulns.f_proof, db.t_service_vulns.f_status, db.t_service_vulns.id, distinct=True) hosts_tr = [] query = (db.t_hosts.id > 0) query = create_hostfilter_query(session.hostfilter, query, 't_services') hosts_dict = db(query).select(db.t_hosts.id, cache=(cache.ram, 30)).as_dict() hostlist = map(lambda x: x['id'], hosts_dict.itervalues()) for svc_vuln in svc_vulns: svc = db.t_services[svc_vuln.f_services_id] if svc is None: logger.error("t_servics_vuln #%s does not link to a t_services.id!" % (svc_vuln.id)) continue if svc.f_hosts_id not in hostlist: continue host_rec = db.t_hosts[svc.f_hosts_id] hosts_tr.append(TR(TD(SPAN(I(_class="icon-trash"), _name="host_del", _id=svc_vuln.id)), TD(A(IMG(_src=URL(request.application, 'static/images', 'terminal.png'), _width="20", _height="20", _style="float:left"), " ", _href="#", _onclick="launchterm('%s')" % (host_rec.id)), host_a_maker(host_rec)), TD("%s/%s" % (svc.f_proto, svc.f_number)), TD(MARKMIN(svc_vuln.f_proof)), TD(svc_vuln.f_status), _id=svc_vuln.id ) ) if len(hosts_tr) > 0: hosts = TABLE(THEAD(TR(TH(T('Del'), _width="5%"), TH(T('Host Information')), TH(T('Port')), TH(T('Proof')), TH(T('Status')), ) ), TBODY(hosts_tr), _id="vulntable", _class="datatable", _width="100%") else: hosts = None else: response.title = "%s :: Invalid Vulnerability ID" return dict(vulninfo={}, refs={}, exploits={}, hosts={}) # vuln form data vuln=crud.read(db.t_vulndata, record) #returns read-only for for t_vulndata vuln.attributes['_id'] = "vuln_record" return dict(vuln=vuln, vulninfo=vulninfo, cvssmetrics=cvssmetrics, refs=refs, exploits=exploits, hosts=hosts)
def customer_xml(): """ Generates an XML file suitable for Customer usage """ from lxml import etree # grab the filter type and value if provided or from the session if session.hostfilter is None: f_type = request.vars.f_type or None f_value = request.vars.f_value or None else: f_type = session.hostfilter[0] f_value = session.hostfilter[1] location_attribute = '{%s}noNameSpaceSchemaLocation' % "http://www.w3.org/2001/XMLSchema-instance" kvasir_results_xml = etree.Element('KvasirResults', attrib={ location_attribute: 'kvasir.xsd', }) summary_xml = etree.SubElement(kvasir_results_xml, 'summary') customer = etree.SubElement(summary_xml, 'customer') customer.text = settings.customer or 'CUSTOMER NAME' assessment = etree.SubElement(summary_xml, 'assessment') assessment.set('type', settings.assessment_type) start_date = etree.SubElement(assessment, 'start-date') start_date.text = settings.start_date or 'START DATE' end_date = etree.SubElement(assessment, 'end-date') end_date.text = settings.end_date or 'END DATE' hosts_xml = etree.SubElement(kvasir_results_xml, 'hosts') os_xml = etree.SubElement(kvasir_results_xml, 'os_records') vulns_xml = etree.SubElement(kvasir_results_xml, 'vulns') # this is a little hack to ensure a record is either blank or None # use it as "if variable not in notin:" notin = [ None, '' ] unknown_cpeid_counter = 0 # go through each host, adding the os, services and vulns accordingly query = create_hostfilter_query([(f_type, f_value), False]) for host_rec in db(query).select(): host_xml = etree.SubElement(hosts_xml, 'host') host_xml.set('ipv4', host_rec.f_ipv4) host_xml.set('assetgroup', host_rec.f_asset_group) if host_rec.f_ipv6: host_xml.set('ipv6', host_rec.f_ipv6) if host_rec.f_macaddr: host_xml.set('macaddr', host_rec.f_macaddr) if host_rec.f_hostname: host_xml.set('hostname', host_rec.f_hostname.decode('utf-8')) if host_rec.f_netbios_name: host_xml.set('netbios', host_rec.f_netbios_name.decode('utf-8')) # build the os information using the highest certainty record highest = (0, None) for os_rec in db(db.t_host_os_refs.f_hosts_id == host_rec.id).select(): if os_rec.f_certainty > highest[0]: highest = (os_rec.f_certainty, os_rec) if highest[0] > 0: # add os element to the host record = highest[1] os = etree.SubElement(host_xml, 'os') os.set('certainty', str(highest[0])) if record.f_class not in notin: os.set('class', record.f_class) if record.f_family not in notin: os.set('family', record.f_family) # since some os records may not have a cpe id we'll mask them with # using their title, replacing spaces with underscores t_os_rec = db.t_os[record.f_os_id] if t_os_rec.f_cpename in notin: cpeid = t_os_rec.f_title.replace(' ', '_') else: cpeid = t_os_rec.f_cpename os.set('id', cpeid) # if the id isn't in os_records, add it if len(os_xml.findall('.//os[@id="%s"]' % (os.get('id', None)))) < 1: os_info_xml = etree.SubElement(os_xml, 'os') os_rec = db.t_os[highest[1].f_os_id] os_info_xml.set('id', cpeid) os_info_xml.set('title', os_rec.f_title) if os_rec.f_vendor not in notin: vendor = etree.SubElement(os_info_xml, 'vendor') vendor.text = os_rec.f_vendor if os_rec.f_product not in notin: product = etree.SubElement(os_info_xml, 'product') product.text = os_rec.f_product if os_rec.f_version not in notin: version = etree.SubElement(os_info_xml, 'version') version.text = os_rec.f_version if os_rec.f_update not in notin: update = etree.SubElement(os_info_xml, 'update') update.text = os_rec.f_update if os_rec.f_edition not in notin: edition = etree.SubElement(os_info_xml, 'edition') edition.text = os_rec.f_edition if os_rec.f_language not in notin: language = etree.SubElement(os_info_xml, 'language') language.text = os_rec.f_language # snmp strings snmp_recs = db(db.t_snmp.f_hosts_id == host_rec.id).select() if len(snmp_recs) > 0: snmp_top_xml = etree.SubElement(hosts_xml, 'snmps') for record in snmp_recs: snmp_xml = etree.SubElement(snmp_top_xml, 'snmp') if record.f_community not in notin: snmp_xml.set('community', record.f_community.decode('utf-8')) snmp_xml.set('version', record.f_version) snmp_xml.set('access', record.f_access) # netbios information netb_record = db(db.t_netbios.f_hosts_id == host_rec.id).select().first() or None if netb_record: netbios_xml = etree.SubElement(hosts_xml, 'netbios') if netb_record.f_type not in notin: netbios_xml.set('type', netb_record.f_type) if netb_record.f_domain not in notin: netbios_xml.set('domain', netb_record.f_domain.decode('utf-8')) if netb_record.f_lockout_limit not in notin: netbios_xml.set('lockout_limit', str(netb_record.f_lockout_limit)) if netb_record.f_lockout_duration not in notin: netbios_xml.set('lockout_duration', str(netb_record.f_lockout_duration)) if netb_record.f_advertised_names is not None: adv_names_xml = etree.SubElement(netbios_xml, 'advertised_names') for name in netb_record.f_advertised_names: name_xml = etree.SubElement(adv_names_xml, 'name') name.text = name.decode('utf-8') # build the services and vulnerabilities services_xml = etree.SubElement(host_xml, 'services') for svc_rec in db(db.t_services.f_hosts_id == host_rec.id).select(): service_xml = etree.SubElement(services_xml, 'service') service_xml.set('proto', svc_rec.f_proto) service_xml.set('number', svc_rec.f_number) if svc_rec.f_name not in notin: name = etree.SubElement(service_xml, 'name') name.text = svc_rec.f_name.decode('utf-8') if svc_rec.f_banner not in notin: banner = etree.SubElement(service_xml, 'banner') banner.text = svc_rec.f_banner.decode('utf-8') # service configuration records svc_info_recs = db(db.t_service_info.f_services_id == svc_rec.id).select() if len(svc_info_recs) > 0: config_xml = etree.SubElement(service_xml, 'configuration') for info_rec in svc_info_recs: rec_xml = etree.SubElement(config_xml, 'config') if info_rec.f_name not in notin: rec_xml.set('name', info_rec.f_name) if info_rec.f_text not in notin: rec_xml.text = info_rec.f_text.decode('utf-8') # vulnerabilities svc_vuln_recs = db(db.t_service_vulns.f_services_id == svc_rec.id).select() if len(svc_vuln_recs) > 0: svc_vulns_xml = etree.SubElement(service_xml, 'vulns') for vuln_rec in svc_vuln_recs: vuln_xml = etree.SubElement(svc_vulns_xml, 'vuln') vuln_xml.set('status', vuln_rec.f_status) vuln_xml.set('id', db.t_vulndata[vuln_rec.f_vulndata_id].f_vulnid) proof = etree.SubElement(vuln_xml, 'proof') proof.text = etree.CDATA(unicode(MARKMIN(vuln_rec.f_proof).xml(), 'utf-8')) # search for the nexpose id in vulns_xml if len(vuln_xml.findall('.//vuln[@id="%s"]' % vuln_xml.get('id', None))) < 1: new_vuln_xml = etree.SubElement(vulns_xml, 'vuln') vulndata = db.t_vulndata[vuln_rec.f_vulndata_id] new_vuln_xml.set('id', vulndata.f_vulnid) new_vuln_xml.set('title', vulndata.f_title) new_vuln_xml.set('severity', str(vulndata.f_severity)) new_vuln_xml.set('pci_sev', str(vulndata.f_pci_sev)) new_vuln_xml.set('cvss_score', str(vulndata.f_cvss_score)) new_vuln_xml.set('cvss_metric', cvss_metrics(vulndata)) description = etree.SubElement(new_vuln_xml, 'description') description.text = etree.CDATA(unicode(MARKMIN(vulndata.f_description).xml(), 'utf-8')) solution = etree.SubElement(new_vuln_xml, 'solution') solution.text = etree.CDATA(unicode(MARKMIN(vulndata.f_solution).xml(), 'utf-8')) # find vulnerability references and add them vuln_refs = db(db.t_vuln_references.f_vulndata_id == vulndata.id).select() if len(vuln_refs) > 0: refs_xml = etree.SubElement(new_vuln_xml, 'references') for ref_rec in vuln_refs: record = db.t_vuln_refs[ref_rec.f_vuln_ref_id] ref_xml = etree.SubElement(refs_xml, 'reference') ref_xml.set('source', record.f_source) ref_xml.text = record.f_text.decode('utf-8') # accounts accounts = db(db.t_accounts.f_services_id == svc_rec.id).select() if len(accounts) > 0: accounts_xml = etree.SubElement(service_xml, 'accounts') for acct_rec in accounts: acct_xml = etree.SubElement(accounts_xml, 'account') if acct_rec.f_username not in notin: elem = etree.SubElement(acct_xml, 'username') elem.text = acct_rec.f_username.decode('utf-8') if acct_rec.f_fullname not in notin: elem = etree.SubElement(acct_xml, 'fullname') elem.text = acct_rec.f_fullname.decode('utf-8') if acct_rec.f_password not in notin: elem = etree.SubElement(acct_xml, 'password') elem.text = acct_rec.f_password.decode('utf-8') if acct_rec.f_hash1 not in notin: elem = etree.SubElement(acct_xml, 'hash1') elem.text = acct_rec.f_hash1 if acct_rec.f_hash1_type not in notin: elem = etree.SubElement(acct_xml, 'hash1_type') elem.text = acct_rec.f_hash1_type if acct_rec.f_hash2 not in notin: elem = etree.SubElement(acct_xml, 'hash2') elem.text = acct_rec.f_hash2 if acct_rec.f_hash2_type not in notin: elem = etree.SubElement(acct_xml, 'hash2_type') elem.text = acct_rec.f_hash2_type if acct_rec.f_uid not in notin: elem = etree.SubElement(acct_xml, 'uid') elem.text = acct_rec.f_uid if acct_rec.f_gid not in notin: elem = etree.SubElement(acct_xml, 'gid') elem.text = acct_rec.f_gid if acct_rec.f_level not in notin: elem = etree.SubElement(acct_xml, 'level') elem.text = acct_rec.f_level if acct_rec.f_domain not in notin: elem = etree.SubElement(acct_xml, 'domain') elem.text = acct_rec.f_domain.decode('utf-8') if acct_rec.f_description not in notin: elem = etree.SubElement(acct_xml, 'description') elem.text = acct_rec.f_description.decode('utf-8') result = etree.tostring(kvasir_results_xml, pretty_print=True, encoding=unicode) return result
def vulninfo_by_vulnid(): """ Returns the vulnerablilty details """ if request.args(0) is None: redirect( URL('default', 'error', vars={'msg': T('No Vulnerability ID sent')})) record = db(db.t_vulndata.f_vulnid == request.args(0)).select().first() if record is not None: # grab vuln references and format the table response.title = "%s :: Vulnerability Popup :: %s" % (settings.title, record.f_vulnid) #cvss_metrics = "AV:%s/AC:%s/Au:%s/C:%s/I:%s/A:%s" % (record.f_cvss_av, # record.f_cvss_ac, # record.f_cvss_au, # record.f_cvss_c, # record.f_cvss_i, # record.f_cvss_a) vulninfo = record cvssmetrics = cvss_metrics(record) refs = LOAD(request.controller, 'vuln_refs_by_vulnid', args=[record.id], ajax=True) exploits = LOAD(request.controller, 'vuln_exploits_by_vulnid', args=[record.id], ajax=True) # TODO: Add hosts with vulnerability -- include service info (proto/port) and # ability to delete vuln from service query = db.t_service_vulns.f_vulndata_id == record.id svc_vulns = db(query).select(db.t_service_vulns.f_services_id, db.t_service_vulns.f_proof, db.t_service_vulns.f_status, db.t_service_vulns.id, distinct=True) hosts_tr = [] query = (db.t_hosts.id > 0) query = create_hostfilter_query(session.hostfilter, query, 't_services') hosts_dict = db(query).select(db.t_hosts.id, cache=(cache.ram, 30)).as_dict() hostlist = map(lambda x: x['id'], hosts_dict.itervalues()) for svc_vuln in svc_vulns: svc = db.t_services[svc_vuln.f_services_id] if svc is None: logger.error( "t_servics_vuln #%s does not link to a t_services.id!" % (svc_vuln.id)) continue if svc.f_hosts_id not in hostlist: continue host_rec = db.t_hosts[svc.f_hosts_id] hosts_tr.append( TR(TD( SPAN(I(_class="icon-trash"), _name="host_del", _id=svc_vuln.id)), TD( A(IMG(_src=URL(request.application, 'static/images', 'terminal.png'), _width="20", _height="20", _style="float:left"), " ", _href="#", _onclick="launchterm('%s')" % (host_rec.id)), host_a_maker(host_rec)), TD("%s/%s" % (svc.f_proto, svc.f_number)), TD(MARKMIN(svc_vuln.f_proof)), TD(svc_vuln.f_status), _id=svc_vuln.id)) if len(hosts_tr) > 0: hosts = TABLE(THEAD( TR( TH(T('Del'), _width="5%"), TH(T('Host Information')), TH(T('Port')), TH(T('Proof')), TH(T('Status')), )), TBODY(hosts_tr), _id="vulntable", _class="datatable", _width="100%") else: hosts = None else: response.title = "%s :: Invalid Vulnerability ID" return dict(vulninfo={}, refs={}, exploits={}, hosts={}) # vuln form data vuln = crud.read(db.t_vulndata, record) #returns read-only for for t_vulndata vuln.attributes['_id'] = "vuln_record" return dict(vuln=vuln, vulninfo=vulninfo, cvssmetrics=cvssmetrics, refs=refs, exploits=exploits, hosts=hosts)
def report(): """ Genereate a HTML-report with fields from statistics, hosts, vulns, and summaries from the wiki """ statistics = db_statistics() adv_stats = adv_db_statistics() graphs = graphs_index() customer = settings.customer assessment = settings.assessment_typed start_date = settings.start_date or 'START DATE' end_date = settings.end_date or 'END DATE' # grab the filter type and value if provided or from the session if session.hostfilter is None: f_type = request.vars.f_type or None f_value = request.vars.f_value or None else: f_type = session.hostfilter[0] f_value = session.hostfilter[1] # this is a little hack to ensure a record is either blank or None # use it as "if variable not in notin:" notin = [None, ''] unknown_cpeid_counter = 0 hosts = [] vulnerabilities = {} # go through each host, adding the os, services and vulns accordingly query = create_hostfilter_query([(f_type, f_value), False]) for host_rec in db(query).select(): host = {} host['ipv4'] = host_rec.f_ipv4 host['asset_group'] = host_rec.f_asset_group if host_rec.f_ipv6: host['ipv6'] = host_rec.f_ipv6 if host_rec.f_macaddr: host['macaddr'] = host_rec.f_macaddr if host_rec.f_hostname: host['hostname'] = host_rec.f_hostname.decode('utf-8') if host_rec.f_netbios_name: host['netbios_name'] = host_rec.f_netbios_name.decode('utf-8') # build the os information using the highest certainty record highest = (0, None) for os_rec in db(db.t_host_os_refs.f_hosts_id == host_rec.id).select(): if os_rec.f_certainty > highest[0]: highest = (os_rec.f_certainty, os_rec) if highest[0] > 0: # add os element to the host record = highest[1] host['os'] = record host['os']['certainty'] = str(highest[0]) if record.f_class not in notin: host['os']['class'] = record.f_class if record.f_family not in notin: host['os']['family'] = record.f_family # since some os records may not have a cpe id we'll mask them with # using their title, replacing spaces with underscores t_os_rec = db.t_os[record.f_os_id] if t_os_rec.f_cpename in notin: cpeid = t_os_rec.f_title.replace(' ', '_') else: cpeid = t_os_rec.f_cpename host['os']['id'] = cpeid # if the id isn't in os_records, add it # if 1: # os_rec = db.t_os[highest[1].f_os_id] # host['os']['id'] = cpeid # host['os']['title'] = os_rec.f_title # # if os_rec.f_vendor not in notin: # host['os']['vendor'] = os_rec.f_vendor # # if os_rec.f_product not in notin: # host['os']['product'] = os_rec.f_product # # if os_rec.f_version not in notin: # host['os']['version'] = os_rec.f_version # # if os_rec.f_update not in notin: # host['os']['update'] = os_rec.f_update # # if os_rec.f_edition not in notin: # host['os']['edition'] = os_rec.f_edition # # if os_rec.f_language not in notin: # host['os']['language'] = os_rec.f_language # snmp strings snmp_recs = db(db.t_snmp.f_hosts_id == host_rec.id).select() if len(snmp_recs) > 0: host['snmps'] = [] for record in snmp_recs: snmp = {} if record.f_community not in notin: snmp['community'] = record.f_community.decode('utf-8') snmp['version'] = record.f_version snmp['access'] = record.f_access host['snmps'].append(snmp) # netbios information netb_record = db( db.t_netbios.f_hosts_id == host_rec.id).select().first() or None if netb_record: host['netbios'] = {} if netb_record.f_type not in notin: host['netbios']['type'] = netb_record.f_type if netb_record.f_domain not in notin: host['netbios']['domain'] = netb_record.f_domain.decode( 'utf-8') if netb_record.f_lockout_limit not in notin: host['netbios']['lockout_limit'] = str( netb_record.f_lockout_limit) if netb_record.f_lockout_duration not in notin: host['netbios']['lockout_duration'] = str( netb_record.f_lockout_duration) if netb_record.f_advertised_names is not None: for name in netb_record.f_advertised_names: host['netbios']['advertised_name'] = name.decode('utf-8') # build the services and vulnerabilities host['services'] = [] for svc_rec in db(db.t_services.f_hosts_id == host_rec.id).select(): service = {} service['proto'] = svc_rec.f_proto service['number'] = int(svc_rec.f_number) if svc_rec.f_name not in notin: service['name'] = svc_rec.f_name.decode('utf-8') else: service['name'] = T('unknown') if svc_rec.f_banner not in notin: service['banner'] = svc_rec.f_banner.decode('utf-8') # service configuration records svc_info_recs = db( db.t_service_info.f_services_id == svc_rec.id).select() if len(svc_info_recs) > 0: service['configs'] = [] for info_rec in svc_info_recs: config = {} if info_rec.f_name not in notin: config['name'] = info_rec.f_name if info_rec.f_text not in notin: config['text'] = info_rec.f_text.decode('utf-8') service['configs'].append(config) # vulnerabilities svc_vuln_recs = db( db.t_service_vulns.f_services_id == svc_rec.id).select() if len(svc_vuln_recs) > 0: service['vulns'] = [] for vuln_rec in svc_vuln_recs: vuln = {} vuln['status'] = vuln_rec.f_status vuln['proof'] = vuln_rec.f_proof vulndata = db.t_vulndata[vuln_rec.f_vulndata_id] vuln['vulninfo'] = vulndata vuln['id'] = vulndata.f_vulnid vuln['title'] = vulndata.f_title vuln['severity'] = str(vulndata.f_severity) vuln['pci_sev'] = str(vulndata.f_pci_sev) vuln['cvss_score'] = str(vulndata.f_cvss_score) vuln['cvssmetrics'] = cvss_metrics(vulndata) vuln['description'] = vulndata.f_description vuln['solution'] = vulndata.f_solution # find vulnerability references and add them vuln_refs = db(db.t_vuln_references.f_vulndata_id == vulndata.id).select() if len(vuln_refs) > 0: vuln['refs'] = [] for ref_rec in vuln_refs: ref = {} record = db.t_vuln_refs[ref_rec.f_vuln_ref_id] ref['source'] = record.f_source ref['text'] = record.f_text.decode('utf-8') vuln['refs'].append(ref) # find vulnerability exploits and add them vuln_exploits = '' #db(db.t_vuln_references.f_vulndata_id == vulndata.id).select() if len(vuln_exploits) > 0: vuln['exploits'] = [] for ref_rec in vuln_refs: ref = {} record = db.t_vuln_refs[ref_rec.f_vuln_ref_id] ref['source'] = record.f_source ref['text'] = record.f_text.decode('utf-8') vuln['refs'].append(ref) if (int(vuln['severity']) > 0): service['vulns'].append(vuln) vuln['hosts'] = [] vulnhost = {} vulnhost['ipv4'] = host['ipv4'] if 'hostname' in host: vulnhost['hostname'] = host['hostname'] else: vulnhost['hostname'] = host['ipv4'] vulnhost['svcproto'] = service['proto'] vulnhost['svcnumber'] = service['number'] vulnhost['status'] = vuln_rec.f_status vulnhost['proof'] = vuln_rec.f_proof vulnhost['url'] = '' if svc_rec.f_name not in notin: vulnhost['svcname'] = svc_rec.f_name.decode( 'utf-8') else: vulnhost['svcname'] = T('unknown') if svc_rec.f_banner not in notin: vulnhost['svcbanner'] = svc_rec.f_banner.decode( 'utf-8') id = str(vuln_rec.f_vulndata_id) if id not in vulnerabilities: vulnerabilities[id] = vuln vulnerabilities[id]['hosts'].append(vulnhost) if len(service['vulns']) is 0: del service['vulns'] host['services'].append(service) # accounts #accounts = db(db.t_accounts.f_services_id == svc_rec.id).select() # if len(accounts) > 0: # host['accounts'] = [] # # for acct_rec in accounts: # account = {} # # if acct_rec.f_username not in notin: # account['username'] = acct_rec.f_username.decode('utf-8') # # if acct_rec.f_fullname not in notin: # account['fullname'] = acct_rec.f_fullname.decode('utf-8') # # if acct_rec.f_password not in notin: # account['password'] = acct_rec.f_password.decode('utf-8') # # if acct_rec.f_hash1 not in notin: # account['hash1'] = acct_rec.f_hash1 # # if acct_rec.f_hash1_type not in notin: # account['hash1_type'] = acct_rec.f_hash1_type # # if acct_rec.f_hash2 not in notin: # account['hash2'] = acct_rec.f_hash2 # # if acct_rec.f_hash2_type not in notin: # account['hash2_type'] = acct_rec.f_hash2_type # # if acct_rec.f_uid not in notin: # account['uid'] = acct_rec.f_uid # # if acct_rec.f_gid not in notin: # account['gid'] = acct_rec.f_gid # # if acct_rec.f_level not in notin: # account['level'] = acct_rec.f_level # # if acct_rec.f_domain not in notin: # account['domain'] = acct_rec.f_domain.decode('utf-8') # # if acct_rec.f_description not in notin: # account['description'] = acct_rec.f_description.decode('utf-8') # host['accounts'].append(account) hosts.append(host) #response.files.append(URL(request.application,'static','js/jquery.sparkline.js')) #get JSON from host.list and use mockjax ext = request.extension request.extension = 'json' hostlist = list() #Not an empty list request.extension = ext #remove the engineer field from the customers report hostlist['aaData'][-1]['10'] = None import re hostlist = re.sub("href=\"[^>]*>([^<]*)", "href=\"#\\1\">\\1", str(hostlist)) listjson = hostlist.replace('\"', '\\\"').replace('\'', '\"').replace( 'L, ', ', ').replace('None', 'null') vulnlst = sorted(vulnerabilities, key=lambda x: int(vulnerabilities[x]['severity']), reverse=True) return dict(vulnlst=vulnlst, vulnerabilities=vulnerabilities, statistics=statistics, adv_stats=adv_stats, graphs=graphs, hosts=hosts, hostfilter=session.hostfilter, listjson=listjson)
def report(): """ Genereate a HTML-report with fields from statistics, hosts, vulns, and summaries from the wiki """ statistics = db_statistics() adv_stats = adv_db_statistics() graphs = graphs_index() customer = settings.customer assessment = settings.assessment_typed start_date = settings.start_date or 'START DATE' end_date = settings.end_date or 'END DATE' # grab the filter type and value if provided or from the session if session.hostfilter is None: f_type = request.vars.f_type or None f_value = request.vars.f_value or None else: f_type = session.hostfilter[0] f_value = session.hostfilter[1] # this is a little hack to ensure a record is either blank or None # use it as "if variable not in notin:" notin = [ None, '' ] unknown_cpeid_counter = 0 hosts = [] vulnerabilities = {} # go through each host, adding the os, services and vulns accordingly query = create_hostfilter_query([(f_type, f_value), False]) for host_rec in db(query).select(): host = {} host['ipv4'] = host_rec.f_ipv4 host['asset_group'] = host_rec.f_asset_group if host_rec.f_ipv6: host['ipv6'] = host_rec.f_ipv6 if host_rec.f_macaddr: host['macaddr'] = host_rec.f_macaddr if host_rec.f_hostname: host['hostname'] = host_rec.f_hostname.decode('utf-8') if host_rec.f_netbios_name: host['netbios_name'] = host_rec.f_netbios_name.decode('utf-8') # build the os information using the highest certainty record highest = (0, None) for os_rec in db(db.t_host_os_refs.f_hosts_id == host_rec.id).select(): if os_rec.f_certainty > highest[0]: highest = (os_rec.f_certainty, os_rec) if highest[0] > 0: # add os element to the host record = highest[1] host['os']=record host['os']['certainty'] = str(highest[0]) if record.f_class not in notin: host['os']['class'] = record.f_class if record.f_family not in notin: host['os']['family'] = record.f_family # since some os records may not have a cpe id we'll mask them with # using their title, replacing spaces with underscores t_os_rec = db.t_os[record.f_os_id] if t_os_rec.f_cpename in notin: cpeid = t_os_rec.f_title.replace(' ', '_') else: cpeid = t_os_rec.f_cpename host['os']['id'] = cpeid # if the id isn't in os_records, add it # if 1: # os_rec = db.t_os[highest[1].f_os_id] # host['os']['id'] = cpeid # host['os']['title'] = os_rec.f_title # # if os_rec.f_vendor not in notin: # host['os']['vendor'] = os_rec.f_vendor # # if os_rec.f_product not in notin: # host['os']['product'] = os_rec.f_product # # if os_rec.f_version not in notin: # host['os']['version'] = os_rec.f_version # # if os_rec.f_update not in notin: # host['os']['update'] = os_rec.f_update # # if os_rec.f_edition not in notin: # host['os']['edition'] = os_rec.f_edition # # if os_rec.f_language not in notin: # host['os']['language'] = os_rec.f_language # snmp strings snmp_recs = db(db.t_snmp.f_hosts_id == host_rec.id).select() if len(snmp_recs) > 0: host['snmps'] = [] for record in snmp_recs: snmp = {} if record.f_community not in notin: snmp['community'] = record.f_community.decode('utf-8') snmp['version'] = record.f_version snmp['access'] = record.f_access host['snmps'].append(snmp) # netbios information netb_record = db(db.t_netbios.f_hosts_id == host_rec.id).select().first() or None if netb_record: host['netbios'] = {} if netb_record.f_type not in notin: host['netbios']['type'] = netb_record.f_type if netb_record.f_domain not in notin: host['netbios']['domain'] = netb_record.f_domain.decode('utf-8') if netb_record.f_lockout_limit not in notin: host['netbios']['lockout_limit'] = str(netb_record.f_lockout_limit) if netb_record.f_lockout_duration not in notin: host['netbios']['lockout_duration'] = str(netb_record.f_lockout_duration) if netb_record.f_advertised_names is not None: for name in netb_record.f_advertised_names: host['netbios']['advertised_name'] = name.decode('utf-8') # build the services and vulnerabilities host['services'] = [] for svc_rec in db(db.t_services.f_hosts_id == host_rec.id).select(): service = {} service['proto'] = svc_rec.f_proto service['number'] = int(svc_rec.f_number) if svc_rec.f_name not in notin: service['name'] = svc_rec.f_name.decode('utf-8') else: service['name'] = T('unknown') if svc_rec.f_banner not in notin: service['banner'] = svc_rec.f_banner.decode('utf-8') # service configuration records svc_info_recs = db(db.t_service_info.f_services_id == svc_rec.id).select() if len(svc_info_recs) > 0: service['configs'] = [] for info_rec in svc_info_recs: config = {} if info_rec.f_name not in notin: config['name'] = info_rec.f_name if info_rec.f_text not in notin: config['text'] = info_rec.f_text.decode('utf-8') service['configs'].append(config) # vulnerabilities svc_vuln_recs = db(db.t_service_vulns.f_services_id == svc_rec.id).select() if len(svc_vuln_recs) > 0: service['vulns'] = [] for vuln_rec in svc_vuln_recs: vuln = {} vuln['status'] = vuln_rec.f_status vuln['proof'] = vuln_rec.f_proof vulndata = db.t_vulndata[vuln_rec.f_vulndata_id] vuln['vulninfo'] = vulndata vuln['id'] = vulndata.f_vulnid vuln['title'] = vulndata.f_title vuln['severity'] = str(vulndata.f_severity) vuln['pci_sev'] = str(vulndata.f_pci_sev) vuln['cvss_score'] = str(vulndata.f_cvss_score) vuln['cvssmetrics'] = cvss_metrics(vulndata) vuln['description'] = vulndata.f_description vuln['solution'] = vulndata.f_solution # find vulnerability references and add them vuln_refs = db(db.t_vuln_references.f_vulndata_id == vulndata.id).select() if len(vuln_refs) > 0: vuln['refs'] = [] for ref_rec in vuln_refs: ref = {} record = db.t_vuln_refs[ref_rec.f_vuln_ref_id] ref['source'] = record.f_source ref['text'] = record.f_text.decode('utf-8') vuln['refs'].append(ref) # find vulnerability exploits and add them vuln_exploits = '' #db(db.t_vuln_references.f_vulndata_id == vulndata.id).select() if len(vuln_exploits) > 0: vuln['exploits'] = [] for ref_rec in vuln_refs: ref = {} record = db.t_vuln_refs[ref_rec.f_vuln_ref_id] ref['source'] = record.f_source ref['text'] = record.f_text.decode('utf-8') vuln['refs'].append(ref) if (int(vuln['severity'])>0): service['vulns'].append(vuln) vuln['hosts'] = [] vulnhost = {} vulnhost['ipv4'] = host['ipv4'] if 'hostname' in host: vulnhost['hostname'] = host['hostname'] else: vulnhost['hostname'] = host['ipv4'] vulnhost['svcproto'] = service['proto'] vulnhost['svcnumber'] = service['number'] vulnhost['status'] = vuln_rec.f_status vulnhost['proof'] = vuln_rec.f_proof vulnhost['url'] = '' if svc_rec.f_name not in notin: vulnhost['svcname'] = svc_rec.f_name.decode('utf-8') else: vulnhost['svcname'] = T('unknown') if svc_rec.f_banner not in notin: vulnhost['svcbanner'] = svc_rec.f_banner.decode('utf-8') id = str(vuln_rec.f_vulndata_id) if id not in vulnerabilities: vulnerabilities[id] = vuln vulnerabilities[id]['hosts'].append(vulnhost) if len(service['vulns']) is 0: del service['vulns'] host['services'].append(service) # accounts #accounts = db(db.t_accounts.f_services_id == svc_rec.id).select() # if len(accounts) > 0: # host['accounts'] = [] # # for acct_rec in accounts: # account = {} # # if acct_rec.f_username not in notin: # account['username'] = acct_rec.f_username.decode('utf-8') # # if acct_rec.f_fullname not in notin: # account['fullname'] = acct_rec.f_fullname.decode('utf-8') # # if acct_rec.f_password not in notin: # account['password'] = acct_rec.f_password.decode('utf-8') # # if acct_rec.f_hash1 not in notin: # account['hash1'] = acct_rec.f_hash1 # # if acct_rec.f_hash1_type not in notin: # account['hash1_type'] = acct_rec.f_hash1_type # # if acct_rec.f_hash2 not in notin: # account['hash2'] = acct_rec.f_hash2 # # if acct_rec.f_hash2_type not in notin: # account['hash2_type'] = acct_rec.f_hash2_type # # if acct_rec.f_uid not in notin: # account['uid'] = acct_rec.f_uid # # if acct_rec.f_gid not in notin: # account['gid'] = acct_rec.f_gid # # if acct_rec.f_level not in notin: # account['level'] = acct_rec.f_level # # if acct_rec.f_domain not in notin: # account['domain'] = acct_rec.f_domain.decode('utf-8') # # if acct_rec.f_description not in notin: # account['description'] = acct_rec.f_description.decode('utf-8') # host['accounts'].append(account) hosts.append(host) #response.files.append(URL(request.application,'static','js/jquery.sparkline.js')) #get JSON from host.list and use mockjax ext = request.extension request.extension = 'json' hostlist = list() #Not an empty list request.extension = ext #remove the engineer field from the customers report hostlist['aaData'][-1]['10']=None import re hostlist = re.sub("href=\"[^>]*>([^<]*)","href=\"#\\1\">\\1", str(hostlist)) listjson=hostlist.replace('\"','\\\"').replace('\'','\"').replace('L, ',', ').replace('None','null') vulnlst=sorted(vulnerabilities, key=lambda x: int(vulnerabilities[x]['severity']), reverse=True) return dict( vulnlst=vulnlst, vulnerabilities=vulnerabilities, statistics=statistics, adv_stats=adv_stats, graphs=graphs, hosts=hosts, hostfilter=session.hostfilter, listjson=listjson)