def list(): aaData = [] response.title = "%s :: SNMP" % (settings.title) if request.extension == "json": rows = db(db.t_snmp.id > 0).select() for r in rows: aTxt = {} aaData.append({ '0': A('edit', _target="snmp_%s" % (r.id), _href=URL('edit', args=r.id)).xml(), '1': host_a_maker(r.f_hosts_id).xml(), '2': r.f_community, '3': r.f_version, '4': r.f_access, 'DT_RowId': r.id }) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result add = AddModal( db.t_snmp, 'Add', 'Add SNMP', 'Add SNMP', #fields=add_fields, cmd='snmptable.fnReloadAjax();', flash="SNMP entry added") db.t_snmp.id.comment = add.create() table = TABLE(THEAD( TR( TH(T('ID'), _width="5%"), TH(T('Host')), TH(T('Community')), TH(T('Version')), TH(T('Access Level')), )), _class="datatable", _id="snmptable", _style="width:100%") return dict(table=table, add=add)
def refs_list(): #class VirtFields(object): # def hostinfo(self): # return host_title_maker(self.t_host_os_refs.f_hosts_id) # def osinfo(self): # return "%s :: %s" % (self.t_host_os_refs.f_os_id.f_cpename, self.t_host_os_refs.f_os_id.f_title) #db.t_host_os_refs.virtualfields.append(VirtFields()) if request.extension == "json": rows=db(db.t_host_os_refs.f_os_id == db.t_os.id).select() aaData = [] for row in rows: atxt = {} atxt['0'] = A("edit", _target="os_refs_update_%s" % (row.t_host_os_refs.id), _href=URL('refs_edit',extension='html',args=row.t_host_os_refs.id)).xml() atxt['1'] = row.t_host_os_refs.f_certainty atxt['2'] = row.t_host_os_refs.f_class atxt['3'] = row.t_host_os_refs.f_family atxt['4'] = host_a_maker(row.t_host_os_refs.f_hosts_id).xml() atxt['5'] = "%s :: %s" % (row.t_os.f_cpename, row.t_os.f_title) atxt['DT_RowId'] = row.t_host_os_refs.id aaData.append(atxt) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result response.title = "%s :: OS/Host References" % (settings.title) form = TABLE(THEAD(TR(TH(T(''), _width="5%"), TH(T('Certainty')), TH(T('Class')), TH(T('Family')), TH(T('Host')), TH(T('OS')), ) ), TFOOT(TR(TH(), TH(), TH(), TH(), TH(), TH())), _class="datatable", _id="ostable", _style="width:100%") add_ref = AddModal( db.t_host_os_refs, 'Link OS', 'Link OS', 'Link OS Reference', #fields=[], cmd='ostable.fnReloadAjax();' ) db.t_host_os_refs.id.comment = add_ref.create() add_os = AddModal( db.t_os, 'Add Non-CPE to OS DB', 'Add Non-CPE to OS DB', 'Add Non-CPE to OS DB', #fields=[], ) db.t_os.id.comment = add_os.create() return dict(form=form, add_ref=add_ref, add_os=add_os)
def list(): aaData = [] response.title = "%s :: SNMP" % (settings.title) if request.extension == "json": rows = db(db.t_snmp.id > 0).select() for r in rows: aTxt = {} aaData.append({ '0': A('edit', _target="snmp_%s" % (r.id), _href=URL('edit', args=r.id)).xml(), '1': host_a_maker(r.f_hosts_id).xml(), '2': r.f_community, '3': r.f_version, '4': r.f_access, 'DT_RowId': r.id }) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result add = AddModal( db.t_snmp, 'Add', 'Add SNMP', 'Add SNMP', #fields=add_fields, cmd='snmptable.fnReloadAjax();', flash="SNMP entry added" ) db.t_snmp.id.comment = add.create() table = TABLE(THEAD(TR(TH(T('ID'), _width="5%"), TH(T('Host')), TH(T('Community')), TH(T('Version')), TH(T('Access Level')), ) ), _class="datatable", _id="snmptable", _style="width:100%") return dict(table=table, add=add)
def list(): """ Returns a list of notes records based upon an host identifier (id, ipv4, ipv6) """ aaData = [] response.title = "%s :: Notes" % (settings.title) if request.args(0) is not None: record = get_host_record(request.args(0)) if record: response.title = "%s :: Notes for %s" % (settings.title, host_title_maker(record)) else: record = None if request.extension == "json": if record: rows = db(db.t_host_notes.f_hosts_id == record.id).select() else: rows = db(db.t_host_notes.id > 0).select() for r in rows: aTxt = {} aaData.append({ '0': A('edit', _target="host_notes_%s" % (r.id), _href=URL('edit', args=r.id)).xml(), '1': host_a_maker(r.f_hosts_id).xml(), '2': r.f_note, 'DT_RowId': r.id }) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result if record: add_fields = ['f_note'] else: add_fields = ['f_hosts_id', 'f_note'] add_note = AddModal( db.t_host_notes, 'Add', 'Add Note', 'Add Note', #fields=add_fields, cmd='notestable.fnReloadAjax();', flash="Note added") if record: db.t_host_notes.f_hosts_id.default = record.id db.t_host_notes.id.comment = add_note.create() notes = TABLE(THEAD( TR( TH(T('ID'), _width="5%"), TH(T('Host'), _width="20%"), TH(T('Note'), _width="95%"), )), _class="datatable", _id="notestable", _style="width:100%") return dict(notes=notes, host=record, add_note=add_note)
def list(): """ Returns a list of evidence based on a host (id, ipv4, ipv6) or all """ import os, string if request.args(0) is not None: record = get_host_record(request.args(0)) if record is None: redirect( URL('default', 'error', vars={'msg': T('Host record not found')})) response.title = "%s :: Evidence for host %s" % ( settings.title, host_title_maker(record)) else: response.title = "%s :: Evidence listing" % (settings.title) record = None aaData = [] if request.extension == "json": if record is None: rows = db(db.t_evidence).select( db.t_evidence.id, db.t_evidence.f_hosts_id, db.t_evidence.f_type, db.t_evidence.f_other_type, db.t_evidence.f_text, db.t_evidence.f_filename, db.t_evidence.f_evidence, db.t_evidence.f_data.len() + 1) else: rows = db(db.t_evidence.f_hosts_id == record.id).select( db.t_evidence.id, db.t_evidence.f_hosts_id, db.t_evidence.f_type, db.t_evidence.f_other_type, db.t_evidence.f_text, db.t_evidence.f_filename, db.t_evidence.f_evidence, db.t_evidence.f_data.len() + 1) for r in rows: atxt = {} cnt = 0 atxt[cnt] = A('edit', _target="evidence_edit_%s" % (r.t_evidence.id), _href=URL('edit', extension='html', args=r.t_evidence.id)).xml() cnt += 1 if record is None: atxt[cnt] = host_a_maker(r.t_evidence.f_hosts_id).xml() cnt += 1 if r.t_evidence.f_other_type: atxt[cnt] = "Other: %s" % (r.t_evidence.f_other_type) else: atxt[cnt] = r.t_evidence.f_type cnt += 1 atxt[cnt] = r.t_evidence.f_text cnt += 1 if r.t_evidence.f_filename is not None: if string.lower(os.path.splitext( r.t_evidence.f_filename)[1]) in ('.png', '.jpeg', '.jpg', '.gif'): atxt[cnt] = A(IMG(_src=URL('download', args=[r.t_evidence.f_evidence]), _width="50%", _height="20%"), _href=URL('download', args=[r.t_evidence.f_evidence]), _target="evidence_image_%s" % (r.t_evidence.id), _id="evidence_image").xml() cnt += 1 atxt[cnt] = "%sb" % ( r._extra['(LENGTH(t_evidence.f_data) + 1)']) cnt += 1 else: atxt[cnt] = A( r.t_evidence.f_filename, _target="evidence_other_%s" % (r.t_evidence.id), _id="evidence_other", _href=URL('download', args=[r.t_evidence.f_evidence])).xml() cnt += 1 atxt[cnt] = "%sb" % ( r._extra['(LENGTH(t_evidence.f_data) + 1)']) cnt += 1 else: atxt[cnt] = r.t_evidence.f_filename cnt += 1 atxt['DT_RowId'] = r.t_evidence.id aaData.append(atxt) return { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } if record: th_rows = ( TH(T(''), _width="5%"), TH(T('Type')), TH(T('Text')), TH(T('Evidence')), TH(T('File Size')), ) else: th_rows = ( TH(T(''), _width="5%"), TH(T('Host')), TH(T('Type')), TH(T('Text')), TH(T('Evidence'), _width="35%"), TH(T('File Size')), ) evidence = TABLE(THEAD(TR(th_rows)), _class="datatable", _id="evidencetable", _style="width:100%") return dict(evidence=evidence, host=record)
def list(): """ Returns a list of notes records based upon an host identifier (id, ipv4, ipv6) """ aaData = [] response.title = "%s :: Notes" % (settings.title) if request.args(0) is not None: record = get_host_record(request.args(0)) if record: response.title = "%s :: Notes for %s" % (settings.title, host_title_maker(record)) else: record = None if request.extension == "json": if record: rows = db(db.t_host_notes.f_hosts_id == record.id).select() else: rows = db(db.t_host_notes.id > 0).select() for r in rows: aTxt = {} aaData.append({ '0': A('edit', _target="host_notes_%s" % (r.id), _href=URL('edit', args=r.id)).xml(), '1': host_a_maker(r.f_hosts_id).xml(), '2': r.f_note, 'DT_RowId': r.id }) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result if record: add_fields = ['f_note'] else: add_fields = ['f_hosts_id', 'f_note'] add_note = AddModal( db.t_host_notes, 'Add', 'Add Note', 'Add Note', #fields=add_fields, cmd='notestable.fnReloadAjax();', flash="Note added" ) if record: db.t_host_notes.f_hosts_id.default = record.id db.t_host_notes.id.comment = add_note.create() notes = TABLE(THEAD(TR(TH(T('ID'), _width="5%"), TH(T('Host'), _width="20%"), TH(T('Note'), _width="95%"), ) ), _class="datatable", _id="notestable", _style="width:100%") return dict(notes=notes, host=record, add_note=add_note)
def list(): from skaldship.general import severity_mapping response.title = "%s :: Services" % (settings.title) if request.extension == 'json': q = (db.t_services.id > 0) proto = request.vars.f_proto pnum = request.vars.f_number if pnum: q &= (db.t_services.f_number == pnum) if proto: q &= (db.t_services.f_protocol == proto) q = create_hostfilter_query(session.hostfilter, q, 't_services') # Datatables Server-side: http://datatables.net/usage/server-side if 'iDisplayStart' in request.vars: start = int(request.vars.iDisplayStart) else: start = 0 if 'iDisplayLength' in request.vars: if request.vars.iDisplayLength == '-1': limit = db(q).count() else: limit = start + int(request.vars.iDisplayLength) else: limit = int(auth.user.f_show_size) srch_data = request.vars.get('sSearch') if srch_data: # sSearch global search box # parse the search into fields (port:num proto:tcp etc) srch_vals = [ ["port", db.t_services.f_number], ["proto", db.t_services.f_proto], ["status", db.t_services.f_status], ["name", db.t_services.f_name], ["banner", db.t_services.f_banner], ["ip", db.t_hosts.f_ipaddr], ["hostname", db.t_hosts.f_hostname], ] parsed = False for val in srch_vals: srch_str = "%s:(?P<f>\w+)" % val[0] srch_res = re.findall(srch_str, srch_data) for res in srch_res: parsed = True if val[0] == 'banner': q &= (val[1].contains(res)) else: q &= (val[1].upper() == res.upper()) if not parsed: q &= db.t_services.f_proto.like("%%%s%%" % request.vars.sSearch) | \ db.t_services.f_number.like("%%%s%%" % request.vars.sSearch) | \ db.t_services.f_name.like("%%%s%%" % request.vars.sSearch) | \ db.t_services.f_banner.like("%%%s%%" % request.vars.sSearch) | \ db.t_services.f_status.like("%%%s%%" % request.vars.sSearch) if request.vars.iSortingCols == '1': cols = ( None, None, None, db.t_services.f_hosts_id, db.t_services.f_proto, db.t_services.f_number, db.t_services.f_status, None, None, None, None, db.t_services.f_name, db.t_services.f_banner, ) orderby = cols[int(request.vars.iSortCol_0)] if request.vars.sSortDir_0 == 'asc': rows = db(q).select(orderby=orderby, limitby=(start, limit)) else: rows = db(q).select(orderby=~orderby, limitby=(start, limit)) else: rows = db(q).select(limitby=(start, limit)) nolimit = db(q).count() aaData = [] # datatable formatting is specific # gather all the vulndata and exploits into a big row # later we'll do a find(lambda: row: row.<db>.<field> == <value>) # to slice it into the bits we need. Maybe it'll be faster? #vulndata = db().select(db.t_vulndata.f_vulnid, db.t_vulndata.id, db.t_exploit_references.f_exploit_id, # left=db.t_exploit_references.on(db.t_vulndata.id==db.t_exploit_references.f_vulndata_id)) for r in rows: atxt = {} vulncount = 0 vulns = db( db.t_service_vulns.f_services_id == r.t_services.id).select( db.t_service_vulns.f_vulndata_id, cache=(cache.ram, 60)) vulnlist = [] explist = [] for vuln in vulns: vuln_rec = db.t_vulndata[vuln.f_vulndata_id] if vuln_rec.f_vulnid not in vulnlist: if settings.use_cvss: vulnlist.append( (vuln_rec.f_vulnid, vuln_rec.f_cvss_score)) else: vulnlist.append( (vuln_rec.f_vulnid, vuln_rec.f_severity)) exploits = db(db.t_exploit_references.f_vulndata_id == vuln.f_vulndata_id).select(cache=(cache.ram, 60)) if len(exploits) > 0: for expinfo in exploits: exp = db.t_exploits[expinfo.f_exploit_id] exp_link = A(exp.f_name, _href=URL('exploits', 'edit', extension='html', args=exp.id), _target='blank') explist.append( TR(TD(exp_link), TD(exp.f_title), TD(exp.f_source), TD(exp.f_rank))) q = r.t_services.t_service_info.select(cache=(cache.ram, 60)) if (len(q) > 0) or (len(explist) > 0) or (len(vulnlist) > 0): atxt['0'] = IMG(_src=URL(request.application, 'static', 'images/details_open.png')).xml() else: atxt['0'] = "" atxt['1'] = A("edit", _target="services_edit_%s" % (r.t_services.id), _href=URL('edit', args=[r.t_services.id], extension='html')).xml() if len(q) > 0: addl = [] for svcinfo in q: addl.append(TR(TD(svcinfo.f_name), TD(svcinfo.f_text))) atxt['2'] = TABLE(THEAD(TR(TH(T('Name')), TH(T('Text')))), TBODY(addl), _class="table table-condensed table-striped", _style="width:100%").xml() else: atxt['2'] = '' host_rec = db.t_hosts[r.t_services.f_hosts_id] atxt['3'] = host_a_maker(host_rec).xml(), atxt['4'] = r.t_services.f_proto # Append A tags around services with HTTP Ports if r.t_services.f_number in HTTP_PORTS and r.t_services.f_proto == "tcp" or r.t_services.f_name == "HTTP": atxt['5'] = A( r.t_services.f_number, _href=URL('default', 'redirect', extension='html', vars={ 'url': "http://%s:%s/" % (host_rec.f_ipaddr, r.t_services.f_number) }), _target="%s-tcp-%s" % (host_rec.f_ipaddr, r.t_services.f_number)).xml() elif r.t_services.f_number in HTTPS_PORTS and r.t_services.f_proto == "tcp" or r.t_services.f_name == "HTTPS": atxt['5'] = A( r.t_services.f_number, _href=URL('default', 'redirect', extension='html', vars={ 'url': "https://%s:%s/" % (host_rec.f_ipaddr, r.t_services.f_number) }), _target="%s-tcp-%s" % (host_rec.f_ipaddr, r.t_services.f_number)).xml() else: atxt['5'] = r.t_services.f_number atxt['6'] = r.t_services.f_status atxt['7'] = len(vulnlist) vulntxt = [] for vuln in vulnlist: color = severity_mapping(vuln[1])[2] vulntxt.append( A(vuln[0], _id="vuln", _target="vulninfo_by_vulnid_%s" % (vuln[0]), _href=URL('vulns', 'vulninfo_by_vulnid', args=[vuln[0]], extension='html'), _style="color:" + color).xml()) atxt['8'] = " :: ".join(vulntxt) if len(explist) > 0: atxt['9'] = "Yes (%d)" % (len(explist)) else: atxt['9'] = '' if len(explist) > 0: atxt['10'] = TABLE(THEAD( TR(TH(T('Name')), TH(T('Title')), TH(T('Source')), TH(T('Rank')))), TBODY(explist), _class="table table-condensed", _style="width:100%").xml() else: atxt['10'] = '' atxt['11'] = r.t_services.f_name atxt['12'] = r.t_services.f_banner atxt['DT_RowId'] = r.t_services.id aaData.append(atxt) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': db(db.t_services).count(), 'iTotalDisplayRecords': nolimit, 'aaData': aaData, } return result else: add = AddModal( db.t_services, 'Add', 'Add', 'Add Service', #fields=[ # 'f_proto', 'f_number', 'f_status', 'f_name', 'f_banner' #], cmd='servicetable.fnReloadAjax();') db.t_services.id.comment = add.create() return dict(add=add)
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 list(): response.title = "%s :: Accounts" % (settings.title) # if no filter is set then we blank it out if session.hostfilter is None: session.hostfilter = [(None, None), False] if request.extension == "json": query = (db.t_accounts.id > 0) & (db.t_accounts.f_services_id == db.t_services.id) query = create_hostfilter_query(session.hostfilter, query, "t_services") if request.vars.hash_type is not None: query &= (db.t_accounts.f_hash1_type == request.vars.hash_type) | ( db.t_accounts.f_hash2_type == request.vars.hash_type ) if request.vars.has_key("iDisplayStart"): start = int(request.vars.iDisplayStart) else: start = 0 if request.vars.has_key("iDisplayLength"): if request.vars.iDisplayLength == "-1": limit = db(query).count() else: limit = start + int(request.vars.iDisplayLength) else: limit = int(auth.user.f_show_size) srch_data = request.vars.get("sSearch") if srch_data: # sSearch global search box # parse the search into fields (port:num proto:tcp etc) srch_vals = [ ["port", db.t_services.f_number], ["proto", db.t_services.f_proto], ["user", db.t_accounts.f_username], ["name", db.t_accounts.f_fullname], ["domain", db.t_accounts.f_domain], ["hash", db.t_accounts.f_hash1], ["hash1", db.t_accounts.f_hash1], ["hash2", db.t_accounts.f_hash2], ["htype", db.t_accounts.f_hash1_type], ["uid", db.t_accounts.f_uid], ["gid", db.t_accounts.f_gid], ["level", db.t_accounts.f_level], ["source", db.t_accounts.f_source], ["desc", db.t_accounts.f_description], ["msg", db.t_accounts.f_message], ["ip", db.t_hosts.f_ipv4], ["ipv4", db.t_hosts.f_ipv4], ["ipv6", db.t_hosts.f_ipv6], ["hostname", db.t_hosts.f_hostname], ] parsed = False for val in srch_vals: srch_str = "%s:(?P<f>\w+)" % val[0] srch_res = re.findall(srch_str, srch_data) for res in srch_res: parsed = True if val[0] in ["source", "desc", "hostname"]: query &= val[1].upper().contains(res.upper()) else: query &= val[1].upper() == res.upper() if not parsed: query &= ( db.t_accounts.f_username.like("%%%s%%" % request.vars.sSearch) | db.t_accounts.f_password.like("%%%s%%" % request.vars.sSearch) | db.t_accounts.f_fullname.like("%%%s%%" % request.vars.sSearch) | db.t_accounts.f_domain.like("%%%s%%" % request.vars.sSearch) | db.t_accounts.f_hash1.like("%%%s%%" % request.vars.sSearch) | db.t_accounts.f_hash2.like("%%%s%%" % request.vars.sSearch) | db.t_accounts.f_source.like("%%%s%%" % request.vars.sSearch) | db.t_accounts.f_message.like("%%%s%%" % request.vars.sSearch) | db.t_accounts.f_description.like("%%%s%%" % request.vars.sSearch) | db.t_hosts.f_ipv4.like("%%%s%%" % request.vars.sSearch) | db.t_hosts.f_ipv6.like("%%%s%%" % request.vars.sSearch) | db.t_hosts.f_hostname.like("%%%s%%" % request.vars.sSearch) ) # total_count = db.t_vulndata.id.count() if request.vars.iSortingCols == "1": # sorting by a column - this is a little trippy because tuples start at 0 # and datatables starts at 1 so we have to subtract 1 from iSortCol_0 cols = ( db.t_accounts.f_compromised, db.t_hosts.f_ipv4, db.t_services.f_number, db.t_accounts.f_username, db.t_accounts.f_fullname, db.t_accounts.f_domain, db.t_accounts.f_password, db.t_accounts.f_hash1_type, db.t_accounts.f_hash1, db.t_accounts.f_hash2_type, db.t_accounts.f_hash2, db.t_accounts.f_uid, db.t_accounts.f_gid, db.t_accounts.f_level, db.t_accounts.f_active, db.t_accounts.f_lockout, db.t_accounts.f_source, db.t_accounts.f_message, db.t_accounts.f_description, ) orderby = cols[int(request.vars.iSortCol_0)] if request.vars.sSortDir_0 == "asc": rows = db(query).select( db.t_accounts.ALL, db.t_hosts.id, db.t_hosts.f_ipv4, db.t_hosts.f_ipv6, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number, orderby=orderby, limitby=(start, limit), cache=(cache.with_prefix(cache.ram, "accounts_list"), 180), ) else: rows = db(query).select( db.t_accounts.ALL, db.t_hosts.id, db.t_hosts.f_ipv4, db.t_hosts.f_ipv6, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number, orderby=~orderby, limitby=(start, limit), cache=(cache.with_prefix(cache.ram, "accounts_list"), 180), ) else: rows = db(query).select( db.t_accounts.ALL, db.t_hosts.id, db.t_hosts.f_ipv4, db.t_hosts.f_ipv6, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number, limitby=(start, limit), cache=(cache.with_prefix(cache.ram, "accounts_list"), 180), ) # rows=db(q).select( # db.t_accounts.ALL, # db.t_hosts.id, # db.t_hosts.f_ipv4, # db.t_hosts.f_ipv6, # db.t_hosts.f_hostname, # db.t_services.f_proto, # db.t_services.f_number, # #cache=(cache.ram,60) # ) aaData = [] # datatable formatting is specific for r in rows: atxt = {} if r.t_accounts.f_compromised == True: atxt["0"] = ( '<div class="acct_compromised" name="row_id" id="%s"><span class="icon-check"></span></div>' % r.t_accounts.id ) else: atxt["0"] = '<div class="acct_uncompromised" name="row_id" id="%s"/>' % r.t_accounts.id # svc = db.t_services[r.f_services_id] atxt["1"] = host_a_maker(r.t_hosts).xml() atxt["2"] = "%s/%s" % (r.t_services.f_proto, r.t_services.f_number) atxt["3"] = DIV( A( I(_class="icon-pencil", _style="display: inline-block;"), _target="accounts_update_%s" % (r.t_accounts.id), _href=URL("edit.html", args=r.t_accounts.id), ), A( "%s" % (r.t_accounts.f_username), _target="_blank", _id="username", _href=URL("by_username", vars={"username": r.t_accounts.f_username}, extension="html"), ), ).xml() atxt["4"] = r.t_accounts.f_fullname atxt["5"] = r.t_accounts.f_domain atxt["6"] = r.t_accounts.f_password atxt["7"] = r.t_accounts.f_hash1_type atxt["8"] = r.t_accounts.f_hash1 atxt["9"] = r.t_accounts.f_hash2_type atxt["10"] = r.t_accounts.f_hash2 atxt["11"] = r.t_accounts.f_uid atxt["12"] = r.t_accounts.f_gid atxt["13"] = r.t_accounts.f_level atxt["14"] = r.t_accounts.f_active atxt["15"] = r.t_accounts.f_source atxt["16"] = r.t_accounts.f_message atxt["17"] = r.t_accounts.f_description atxt["DT_RowId"] = str(r.t_accounts.id) aaData.append(atxt) result = { "sEcho": request.vars.sEcho, "iTotalDisplayRecords": db(query).count(), "iTotalRecords": db(db.t_accounts).count(), "aaData": aaData, "query": db._lastsql, } return result rows = db(db.t_accounts).select( db.t_accounts.f_hash1_type, groupby=db.t_accounts.f_hash1_type, cache=(cache.ram, 60) ) hash_types = [] for r in rows: # if r.f_hash2_type is not None: # hash_types.append("%s/%s" % (r.f_hash1_type, r.f_hash2_type)) # else: hash_types.append(r.f_hash1_type) form = TABLE( THEAD( TR( TH(T("C"), _width="1%"), TH(T("Host")), TH(T("Port")), TH(T("Username")), TH(T("Fullname")), TH(T("Domain")), TH(T("Password")), TH(T("Hash 1 Type")), TH(T("Hash 1")), TH(T("Hash 2 Type")), TH(T("Hash 2")), TH(T("UID")), TH(T("GID")), TH(T("Level")), TH(T("Active")), TH(T("Source")), TH(T("Message")), TH(T("Description")), ) ), _class="datatable", _id="accounttable", _style="width:100%", ) add = AddModal( db.t_accounts, "Add", "Add", "Add Account", # fields=[], cmd="accounttable.fnReloadAjax();", ) services = db(db.t_services.f_hosts_id > 0).select(cache=(cache.ram, 30)) svc_set = [] for svc in services: svc_set.append( [svc.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[svc.f_hosts_id]), svc.f_proto, svc.f_number)] ) db.t_accounts.f_services_id.requires = IS_IN_SET(svc_set) db.t_accounts.id.comment = add.create() return dict(form=form, hash_types=hash_types, add=add)
def list(): """ Returns a list of evidence based on a host (id, ipv4, ipv6) or all """ import os, string if request.args(0) is not None: record = get_host_record(request.args(0)) if record is None: redirect(URL("default", "error", vars={"msg": T("Host record not found")})) response.title = "%s :: Evidence for host %s" % (settings.title, host_title_maker(record)) else: response.title = "%s :: Evidence listing" % (settings.title) record = None aaData = [] if request.extension == "json": if record is None: rows = db(db.t_evidence).select( db.t_evidence.id, db.t_evidence.f_hosts_id, db.t_evidence.f_type, db.t_evidence.f_other_type, db.t_evidence.f_text, db.t_evidence.f_filename, db.t_evidence.f_evidence, db.t_evidence.f_data.len() + 1, ) else: rows = db(db.t_evidence.f_hosts_id == record.id).select( db.t_evidence.id, db.t_evidence.f_hosts_id, db.t_evidence.f_type, db.t_evidence.f_other_type, db.t_evidence.f_text, db.t_evidence.f_filename, db.t_evidence.f_evidence, db.t_evidence.f_data.len() + 1, ) for r in rows: atxt = {} cnt = 0 atxt[cnt] = A( "edit", _target="evidence_edit_%s" % (r.t_evidence.id), _href=URL("edit", extension="html", args=r.t_evidence.id), ).xml() cnt += 1 if record is None: atxt[cnt] = host_a_maker(r.t_evidence.f_hosts_id).xml() cnt += 1 if r.t_evidence.f_other_type: atxt[cnt] = "Other: %s" % (r.t_evidence.f_other_type) else: atxt[cnt] = r.t_evidence.f_type cnt += 1 atxt[cnt] = r.t_evidence.f_text cnt += 1 if r.t_evidence.f_filename is not None: if string.lower(os.path.splitext(r.t_evidence.f_filename)[1]) in (".png", ".jpeg", ".jpg", ".gif"): atxt[cnt] = A( IMG(_src=URL("download", args=[r.t_evidence.f_evidence]), _width="50%", _height="20%"), _href=URL("download", args=[r.t_evidence.f_evidence]), _target="evidence_image_%s" % (r.t_evidence.id), _id="evidence_image", ).xml() cnt += 1 atxt[cnt] = "%sb" % (r._extra["(LENGTH(t_evidence.f_data) + 1)"]) cnt += 1 else: atxt[cnt] = A( r.t_evidence.f_filename, _target="evidence_other_%s" % (r.t_evidence.id), _id="evidence_other", _href=URL("download", args=[r.t_evidence.f_evidence]), ).xml() cnt += 1 atxt[cnt] = "%sb" % (r._extra["(LENGTH(t_evidence.f_data) + 1)"]) cnt += 1 else: atxt[cnt] = r.t_evidence.f_filename cnt += 1 atxt["DT_RowId"] = r.t_evidence.id aaData.append(atxt) return {"sEcho": request.vars.sEcho, "iTotalRecords": len(aaData), "aaData": aaData} if record: th_rows = (TH(T(""), _width="5%"), TH(T("Type")), TH(T("Text")), TH(T("Evidence")), TH(T("File Size"))) else: th_rows = ( TH(T(""), _width="5%"), TH(T("Host")), TH(T("Type")), TH(T("Text")), TH(T("Evidence"), _width="35%"), TH(T("File Size")), ) evidence = TABLE(THEAD(TR(th_rows)), _class="datatable", _id="evidencetable", _style="width:100%") return dict(evidence=evidence, host=record)
def list(): response.title = "%s :: Accounts" % (settings.title) if request.extension == 'json': query = (db.t_accounts.id > 0) & (db.t_accounts.f_services_id == db.t_services.id) query = create_hostfilter_query(session.hostfilter, query, 't_services') if request.vars.hash_type is not None: query &= ((db.t_accounts.f_hash1_type == request.vars.hash_type) | (db.t_accounts.f_hash2_type == request.vars.hash_type)) if request.vars.has_key('iDisplayStart'): start = int(request.vars.iDisplayStart) else: start = 0 if request.vars.has_key('iDisplayLength'): if request.vars.iDisplayLength == '-1': limit = db(query).count() else: limit = start + int(request.vars.iDisplayLength) else: limit = int(auth.user.f_show_size) srch_data = request.vars.get('sSearch') if srch_data: # sSearch global search box # parse the search into fields (port:num proto:tcp etc) srch_vals = [ ["port", db.t_services.f_number], ["proto", db.t_services.f_proto], ["user", db.t_accounts.f_username], ["name", db.t_accounts.f_fullname], ["domain", db.t_accounts.f_domain], ["hash", db.t_accounts.f_hash1], ["hash1", db.t_accounts.f_hash1], ["hash2", db.t_accounts.f_hash2], ["htype", db.t_accounts.f_hash1_type], ["uid", db.t_accounts.f_uid], ["gid", db.t_accounts.f_gid], ["level", db.t_accounts.f_level], ["source", db.t_accounts.f_source], ["desc", db.t_accounts.f_description], ["msg", db.t_accounts.f_message], ["ip", db.t_hosts.f_ipaddr], ["hostname", db.t_hosts.f_hostname], ] parsed = False for val in srch_vals: srch_str = "%s:(?P<f>\w+)" % val[0] srch_res = re.findall(srch_str, srch_data) for res in srch_res: parsed = True if val[0] in ['source', 'desc', 'hostname']: query &= (val[1].upper().contains(res.upper())) else: query &= (val[1].upper() == res.upper()) if not parsed: query &= db.t_accounts.f_username.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_password.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_fullname.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_domain.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_hash1.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_hash2.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_source.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_message.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_description.like("%%%s%%" % request.vars.sSearch) | \ db.t_hosts.f_ipaddr.like("%%%s%%" % request.vars.sSearch) | \ db.t_hosts.f_hostname.like("%%%s%%" % request.vars.sSearch) #total_count = db.t_vulndata.id.count() if request.vars.iSortingCols == '1': # sorting by a column - this is a little trippy because tuples start at 0 # and datatables starts at 1 so we have to subtract 1 from iSortCol_0 cols = (db.t_accounts.f_compromised, db.t_hosts.f_ipaddr, db.t_services.f_number, db.t_accounts.f_username, db.t_accounts.f_fullname, db.t_accounts.f_domain, db.t_accounts.f_password, db.t_accounts.f_hash1_type, db.t_accounts.f_hash1, db.t_accounts.f_hash2_type, db.t_accounts.f_hash2, db.t_accounts.f_uid, db.t_accounts.f_gid, db.t_accounts.f_level, db.t_accounts.f_active, db.t_accounts.f_lockout, db.t_accounts.f_source, db.t_accounts.f_message, db.t_accounts.f_description) orderby = cols[int(request.vars.iSortCol_0)] if request.vars.sSortDir_0 == 'asc': rows = db(query).select(db.t_accounts.ALL, db.t_hosts.id, db.t_hosts.f_ipaddr, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number, orderby=orderby, limitby=(start, limit), cache=(cache.with_prefix( cache.ram, "accounts_list"), 180)) else: rows = db(query).select(db.t_accounts.ALL, db.t_hosts.id, db.t_hosts.f_ipaddr, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number, orderby=~orderby, limitby=(start, limit), cache=(cache.with_prefix( cache.ram, "accounts_list"), 180)) else: rows = db(query).select(db.t_accounts.ALL, db.t_hosts.id, db.t_hosts.f_ipaddr, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number, limitby=(start, limit), cache=(cache.with_prefix( cache.ram, "accounts_list"), 180)) #rows=db(q).select( # db.t_accounts.ALL, # db.t_hosts.id, # db.t_hosts.f_ipaddr, # db.t_hosts.f_hostname, # db.t_services.f_proto, # db.t_services.f_number, # #cache=(cache.ram,60) #) aaData = [] # datatable formatting is specific for r in rows: atxt = {} if r.t_accounts.f_compromised == True: atxt[ '0'] = '<div class="acct_compromised" name="row_id" id="%s"><span class="icon-check"></span></div>' % r.t_accounts.id else: atxt[ '0'] = '<div class="acct_uncompromised" name="row_id" id="%s"/>' % r.t_accounts.id #svc = db.t_services[r.f_services_id] atxt['1'] = host_a_maker(r.t_hosts).xml() atxt['2'] = "%s/%s" % (r.t_services.f_proto, r.t_services.f_number) atxt['3'] = DIV(A(I(_class="icon-pencil", _style="display: inline-block;"), _target="accounts_update_%s" % (r.t_accounts.id), \ _href=URL('edit.html', args=r.t_accounts.id), \ ), A("%s" % (r.t_accounts.f_username), \ _target="_blank", _id="username", \ _href=URL("by_username", vars={'username':r.t_accounts.f_username}, extension="html"), \ ) ).xml() atxt['4'] = r.t_accounts.f_fullname atxt['5'] = r.t_accounts.f_domain atxt['6'] = r.t_accounts.f_password atxt['7'] = r.t_accounts.f_hash1_type atxt['8'] = r.t_accounts.f_hash1 atxt['9'] = r.t_accounts.f_hash2_type atxt['10'] = r.t_accounts.f_hash2 atxt['11'] = r.t_accounts.f_uid atxt['12'] = r.t_accounts.f_gid atxt['13'] = r.t_accounts.f_level atxt['14'] = r.t_accounts.f_active atxt['15'] = r.t_accounts.f_source atxt['16'] = r.t_accounts.f_message atxt['17'] = r.t_accounts.f_description atxt['DT_RowId'] = str(r.t_accounts.id) aaData.append(atxt) result = { 'sEcho': request.vars.sEcho, 'iTotalDisplayRecords': db(query).count(), 'iTotalRecords': db(db.t_accounts).count(), 'aaData': aaData, 'query': db._lastsql, } return result rows = db(db.t_accounts).select(db.t_accounts.f_hash1_type, groupby=db.t_accounts.f_hash1_type, cache=(cache.ram, 60)) hash_types = [] for r in rows: #if r.f_hash2_type is not None: # hash_types.append("%s/%s" % (r.f_hash1_type, r.f_hash2_type)) #else: hash_types.append(r.f_hash1_type) form = TABLE(THEAD( TR( TH(T('C'), _width="1%"), TH(T('Host')), TH(T('Port')), TH(T('Username')), TH(T('Fullname')), TH(T('Domain')), TH(T('Password')), TH(T('Hash 1 Type')), TH(T('Hash 1')), TH(T('Hash 2 Type')), TH(T('Hash 2')), TH(T('UID')), TH(T('GID')), TH(T('Level')), TH(T('Active')), TH(T('Source')), TH(T('Message')), TH(T('Description')), )), _class="datatable", _id="accounttable", _style="width:100%") add = AddModal( db.t_accounts, 'Add', 'Add', 'Add Account', #fields=[], cmd='accounttable.fnReloadAjax();') services = db(db.t_services.f_hosts_id > 0).select(cache=(cache.ram, 30)) svc_set = [] for svc in services: svc_set.append([ svc.id, "%s :: %s/%s" % (host_title_maker( db.t_hosts[svc.f_hosts_id]), svc.f_proto, svc.f_number) ]) db.t_accounts.f_services_id.requires = IS_IN_SET(svc_set) db.t_accounts.id.comment = add.create() return dict(form=form, hash_types=hash_types, add=add)
def domain_detail(): """Creates a page of all netbios related information for a workgroup/domain""" from gluon.serializers import json aaData = [] acctData = [] response.title = "%s :: NetBIOS Details" % (settings.title) if not request.vars.domain: response.title = "%s :: NetBIOS Details for ALL" % (settings.title) query = (db.t_netbios.id>0) else: response.title = "%s :: NetBIOS Details for %s" % (settings.title, request.vars.domain) query = (db.t_netbios.f_domain == request.vars.domain) query &= (db.t_netbios.f_hosts_id == db.t_hosts.id) # pull the list of all servers in a NetBIOS Domain servers = db(query)(db.t_netbios).select() for server in servers: #query = (db.t_accounts.f_services_id == db.t_services.id) # go through each service looking for any compr accounts, accts_list = [] for svc in server.t_hosts.t_services.select(): query = (db.t_accounts.f_services_id == db.t_services.id) query &= (db.t_services.id == svc.id) query &= ((db.t_accounts.f_password != None) | (db.t_accounts.f_hash1 != None)) for accts in db(query).select(): accts_list.append((accts.t_accounts.f_username, accts.t_accounts.f_password, accts.t_accounts.f_level, "%s:%s" % (accts.t_accounts.f_hash1, accts.t_accounts.f_hash2), accts.t_accounts.f_source, "%s/%s (%s)" % (accts.t_services.f_proto, accts.t_services.f_number, accts.t_services.f_name), )) atxt = [] if len(accts_list) > 0: atxt.append(TD(IMG(_src=URL(request.application,'static','images/details_open.png')))) else: atxt.append(TD()) atxt.append(TD(host_a_maker(server.t_hosts))) atxt.append(TD(json(accts_list))) atxt.append(TD(server.t_netbios.f_domain)) atxt.append(TD(server.t_netbios.f_type)) atxt.append(TD(server.t_netbios.f_lockout_duration)) atxt.append(TD(server.t_netbios.f_shares)) aaData.append(TR(atxt)) table = TABLE(THEAD(TR(TH('', _width="5%"), TH(T('Host')), TH(T('Compr. Accts')), TH(T('Domain')), TH(T('Type')), TH(T('Lockout Duration')), TH(T('Shares')) ) ), TBODY(aaData), _class="datatable", _id="netbiostable", _style="width:100%") domains= [] for domain in db(db.t_netbios).select(db.t_netbios.f_domain, distinct=True): domains.append(domain.f_domain) return dict(table=table, domains=domains)
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 domain_detail(): """Creates a page of all netbios related information for a workgroup/domain""" from gluon.serializers import json aaData = [] acctData = [] response.title = "%s :: NetBIOS Details" % (settings.title) if not request.vars.domain: response.title = "%s :: NetBIOS Details for ALL" % (settings.title) query = (db.t_netbios.id > 0) else: response.title = "%s :: NetBIOS Details for %s" % (settings.title, request.vars.domain) query = (db.t_netbios.f_domain == request.vars.domain) query &= (db.t_netbios.f_hosts_id == db.t_hosts.id) # pull the list of all servers in a NetBIOS Domain servers = db(query)(db.t_netbios).select() for server in servers: #query = (db.t_accounts.f_services_id == db.t_services.id) # go through each service looking for any compr accounts, accts_list = [] for svc in server.t_hosts.t_services.select(): query = (db.t_accounts.f_services_id == db.t_services.id) query &= (db.t_services.id == svc.id) query &= ((db.t_accounts.f_password != None) | (db.t_accounts.f_hash1 != None)) for accts in db(query).select(): accts_list.append(( accts.t_accounts.f_username, accts.t_accounts.f_password, accts.t_accounts.f_level, "%s:%s" % (accts.t_accounts.f_hash1, accts.t_accounts.f_hash2), accts.t_accounts.f_source, "%s/%s (%s)" % (accts.t_services.f_proto, accts.t_services.f_number, accts.t_services.f_name), )) atxt = [] if len(accts_list) > 0: atxt.append( TD( IMG(_src=URL(request.application, 'static', 'images/details_open.png')))) else: atxt.append(TD()) atxt.append(TD(host_a_maker(server.t_hosts))) atxt.append(TD(json(accts_list))) atxt.append(TD(server.t_netbios.f_domain)) atxt.append(TD(server.t_netbios.f_type)) atxt.append(TD(server.t_netbios.f_lockout_duration)) atxt.append(TD(server.t_netbios.f_shares)) aaData.append(TR(atxt)) table = TABLE(THEAD( TR(TH('', _width="5%"), TH(T('Host')), TH(T('Compr. Accts')), TH(T('Domain')), TH(T('Type')), TH(T('Lockout Duration')), TH(T('Shares')))), TBODY(aaData), _class="datatable", _id="netbiostable", _style="width:100%") domains = [] for domain in db(db.t_netbios).select(db.t_netbios.f_domain, distinct=True): domains.append(domain.f_domain) return dict(table=table, domains=domains)
def list(): response.title = "%s :: Accounts" % (settings.title) if request.extension == 'json': query = (db.t_accounts.id > 0) & (db.t_accounts.f_services_id== db.t_services.id) query = create_hostfilter_query(session.hostfilter, query, 't_services') if request.vars.hash_type is not None: query &= ((db.t_accounts.f_hash1_type == request.vars.hash_type) | (db.t_accounts.f_hash2_type == request.vars.hash_type)) if request.vars.has_key('iDisplayStart'): start = int(request.vars.iDisplayStart) else: start = 0 if request.vars.has_key('iDisplayLength'): if request.vars.iDisplayLength == '-1': limit = db(query).count() else: limit = start + int(request.vars.iDisplayLength) else: limit = int(auth.user.f_show_size) srch_data = request.vars.get('sSearch') if srch_data: # sSearch global search box # parse the search into fields (port:num proto:tcp etc) srch_vals = [ ["port", db.t_services.f_number], ["proto", db.t_services.f_proto], ["user", db.t_accounts.f_username], ["name", db.t_accounts.f_fullname], ["domain", db.t_accounts.f_domain], ["hash", db.t_accounts.f_hash1], ["hash1", db.t_accounts.f_hash1], ["hash2", db.t_accounts.f_hash2], ["htype", db.t_accounts.f_hash1_type], ["uid", db.t_accounts.f_uid], ["gid", db.t_accounts.f_gid], ["level", db.t_accounts.f_level], ["source", db.t_accounts.f_source], ["desc", db.t_accounts.f_description], ["msg", db.t_accounts.f_message], ["ip", db.t_hosts.f_ipaddr], ["hostname", db.t_hosts.f_hostname], ] parsed = False for val in srch_vals: srch_str = "%s:(?P<f>\w+)" % val[0] srch_res = re.findall(srch_str, srch_data) for res in srch_res: parsed = True if val[0] in ['source', 'desc', 'hostname']: query &= (val[1].upper().contains(res.upper())) else: query &= (val[1].upper() == res.upper()) if not parsed: query &= db.t_accounts.f_username.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_password.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_fullname.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_domain.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_hash1.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_hash2.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_source.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_message.like("%%%s%%" % request.vars.sSearch) | \ db.t_accounts.f_description.like("%%%s%%" % request.vars.sSearch) | \ db.t_hosts.f_ipaddr.like("%%%s%%" % request.vars.sSearch) | \ db.t_hosts.f_hostname.like("%%%s%%" % request.vars.sSearch) #total_count = db.t_vulndata.id.count() if request.vars.iSortingCols == '1': # sorting by a column - this is a little trippy because tuples start at 0 # and datatables starts at 1 so we have to subtract 1 from iSortCol_0 cols = ( db.t_accounts.f_compromised, db.t_hosts.f_ipaddr, db.t_services.f_number, db.t_accounts.f_username, db.t_accounts.f_fullname, db.t_accounts.f_domain, db.t_accounts.f_password, db.t_accounts.f_hash1_type, db.t_accounts.f_hash1, db.t_accounts.f_hash2_type, db.t_accounts.f_hash2, db.t_accounts.f_uid, db.t_accounts.f_gid, db.t_accounts.f_level, db.t_accounts.f_active, db.t_accounts.f_lockout, db.t_accounts.f_source, db.t_accounts.f_message, db.t_accounts.f_description ) orderby = cols[int(request.vars.iSortCol_0) ] if request.vars.sSortDir_0 == 'asc': rows=db(query).select( db.t_accounts.ALL, db.t_hosts.id, db.t_hosts.f_ipaddr, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number, orderby=orderby, limitby=(start, limit), cache=(cache.with_prefix(cache.ram, "accounts_list"), 180)) else: rows=db(query).select( db.t_accounts.ALL, db.t_hosts.id, db.t_hosts.f_ipaddr, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number, orderby=~orderby, limitby=(start, limit), cache=(cache.with_prefix(cache.ram, "accounts_list"), 180)) else: rows=db(query).select( db.t_accounts.ALL, db.t_hosts.id, db.t_hosts.f_ipaddr, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number, limitby=(start,limit), cache=(cache.with_prefix(cache.ram, "accounts_list"), 180)) #rows=db(q).select( # db.t_accounts.ALL, # db.t_hosts.id, # db.t_hosts.f_ipaddr, # db.t_hosts.f_hostname, # db.t_services.f_proto, # db.t_services.f_number, # #cache=(cache.ram,60) #) aaData = [] # datatable formatting is specific for r in rows: atxt = {} if r.t_accounts.f_compromised == True: atxt['0'] = '<div class="acct_compromised" name="row_id" id="%s"><span class="icon-check"></span></div>' % r.t_accounts.id else: atxt['0'] = '<div class="acct_uncompromised" name="row_id" id="%s"/>' % r.t_accounts.id #svc = db.t_services[r.f_services_id] atxt['1'] = host_a_maker(r.t_hosts).xml() atxt['2'] = "%s/%s" % (r.t_services.f_proto, r.t_services.f_number) atxt['3'] = DIV(A(I(_class="icon-pencil", _style="display: inline-block;"), _target="accounts_update_%s" % (r.t_accounts.id), \ _href=URL('edit.html', args=r.t_accounts.id), \ ), A("%s" % (r.t_accounts.f_username), \ _target="_blank", _id="username", \ _href=URL("by_username", vars={'username':r.t_accounts.f_username}, extension="html"), \ ) ).xml() atxt['4'] = r.t_accounts.f_fullname atxt['5'] = r.t_accounts.f_domain atxt['6'] = r.t_accounts.f_password atxt['7'] = r.t_accounts.f_hash1_type atxt['8'] = r.t_accounts.f_hash1 atxt['9'] = r.t_accounts.f_hash2_type atxt['10'] = r.t_accounts.f_hash2 atxt['11'] = r.t_accounts.f_uid atxt['12'] = r.t_accounts.f_gid atxt['13'] = r.t_accounts.f_level atxt['14'] = r.t_accounts.f_active atxt['15'] = r.t_accounts.f_source atxt['16'] = r.t_accounts.f_message atxt['17'] = r.t_accounts.f_description atxt['DT_RowId'] = str(r.t_accounts.id) aaData.append(atxt) result = { 'sEcho': request.vars.sEcho, 'iTotalDisplayRecords': db(query).count(), 'iTotalRecords': db(db.t_accounts).count(), 'aaData': aaData, 'query': db._lastsql, } return result rows=db(db.t_accounts).select(db.t_accounts.f_hash1_type, groupby=db.t_accounts.f_hash1_type, cache=(cache.ram, 60)) hash_types=[] for r in rows: #if r.f_hash2_type is not None: # hash_types.append("%s/%s" % (r.f_hash1_type, r.f_hash2_type)) #else: hash_types.append(r.f_hash1_type) form = TABLE(THEAD(TR(TH(T('C'), _width="1%"), TH(T('Host')), TH(T('Port')), TH(T('Username')), TH(T('Fullname')), TH(T('Domain')), TH(T('Password')), TH(T('Hash 1 Type')), TH(T('Hash 1')), TH(T('Hash 2 Type')), TH(T('Hash 2')), TH(T('UID')), TH(T('GID')), TH(T('Level')), TH(T('Active')), TH(T('Source')), TH(T('Message')), TH(T('Description')), ) ), _class="datatable", _id="accounttable", _style="width:100%") add = AddModal( db.t_accounts, 'Add', 'Add', 'Add Account', #fields=[], cmd='accounttable.fnReloadAjax();' ) services = db(db.t_services.f_hosts_id > 0).select(cache=(cache.ram,30)) svc_set = [] for svc in services: svc_set.append([svc.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[svc.f_hosts_id]), svc.f_proto, svc.f_number)]) db.t_accounts.f_services_id.requires = IS_IN_SET(svc_set) db.t_accounts.id.comment = add.create() return dict(form=form, hash_types=hash_types, add=add)
def list(): from skaldship.general import severity_mapping response.title = "%s :: Services" % (settings.title) if request.extension == 'json': q = (db.t_services.id > 0) proto = request.vars.f_proto pnum = request.vars.f_number if pnum: q &= (db.t_services.f_number == pnum) if proto: q &= (db.t_services.f_protocol == proto) q = create_hostfilter_query(session.hostfilter, q, 't_services') # Datatables Server-side: http://datatables.net/usage/server-side if request.vars.has_key('iDisplayStart'): start = int(request.vars.iDisplayStart) else: start = 0 if request.vars.has_key('iDisplayLength'): if request.vars.iDisplayLength == '-1': limit = db(q).count() else: limit = start + int(request.vars.iDisplayLength) else: limit = int(auth.user.f_show_size) srch_data = request.vars.get('sSearch') if srch_data: # sSearch global search box # parse the search into fields (port:num proto:tcp etc) srch_vals = [ ["port", db.t_services.f_number], ["proto", db.t_services.f_proto], ["status", db.t_services.f_status], ["name", db.t_services.f_name], ["banner", db.t_services.f_banner], ["ip", db.t_hosts.f_ipaddr], ["hostname", db.t_hosts.f_hostname], ] parsed = False for val in srch_vals: srch_str = "%s:(?P<f>\w+)" % val[0] srch_res = re.findall(srch_str, srch_data) for res in srch_res: parsed = True if val[0] == 'banner': q &= (val[1].contains(res)) else: q &= (val[1].upper() == res.upper()) if not parsed: q &= db.t_services.f_proto.like("%%%s%%" % request.vars.sSearch) | \ db.t_services.f_number.like("%%%s%%" % request.vars.sSearch) | \ db.t_services.f_name.like("%%%s%%" % request.vars.sSearch) | \ db.t_services.f_banner.like("%%%s%%" % request.vars.sSearch) | \ db.t_services.f_status.like("%%%s%%" % request.vars.sSearch) if request.vars.iSortingCols == '1': cols = ( None, None, None, db.t_services.f_hosts_id, db.t_services.f_proto, db.t_services.f_number, db.t_services.f_status, None, None, None, None, db.t_services.f_name, db.t_services.f_banner, ) orderby = cols[int(request.vars.iSortCol_0)] if request.vars.sSortDir_0 == 'asc': rows=db(q).select(orderby=orderby, limitby=(start, limit)) else: rows=db(q).select(orderby=~orderby, limitby=(start, limit)) else: rows=db(q).select(limitby=(start, limit)) nolimit = db(q).count() aaData = [] # datatable formatting is specific # gather all the vulndata and exploits into a big row # later we'll do a find(lambda: row: row.<db>.<field> == <value>) # to slice it into the bits we need. Maybe it'll be faster? #vulndata = db().select(db.t_vulndata.f_vulnid, db.t_vulndata.id, db.t_exploit_references.f_exploit_id, # left=db.t_exploit_references.on(db.t_vulndata.id==db.t_exploit_references.f_vulndata_id)) for r in rows: atxt = {} vulncount = 0 vulns = db(db.t_service_vulns.f_services_id==r.t_services.id).select(db.t_service_vulns.f_vulndata_id, cache=(cache.ram, 60)) vulnlist = [] explist=[] for vuln in vulns: vuln_rec = db.t_vulndata[vuln.f_vulndata_id] if vuln_rec.f_vulnid not in vulnlist: if settings.use_cvss: vulnlist.append((vuln_rec.f_vulnid, vuln_rec.f_cvss_score)) else: vulnlist.append((vuln_rec.f_vulnid, vuln_rec.f_severity)) exploits = db(db.t_exploit_references.f_vulndata_id == vuln.f_vulndata_id).select(cache=(cache.ram, 60)) if len(exploits) > 0: for expinfo in exploits: exp = db.t_exploits[expinfo.f_exploit_id] exp_link = A(exp.f_name, _href=URL('exploits', 'edit', extension='html', args=exp.id), _target='blank') explist.append(TR(TD(exp_link), TD(exp.f_title), TD(exp.f_source), TD(exp.f_rank) ) ) q = r.t_services.t_service_info.select(cache=(cache.ram, 60)) if (len(q) > 0) or (len(explist) > 0) or (len(vulnlist) > 0): atxt['0'] = IMG(_src=URL(request.application,'static','images/details_open.png')).xml() else: atxt['0'] = "" atxt['1'] = A("edit", _target="services_edit_%s" % (r.t_services.id), _href=URL('edit', args=[r.t_services.id], extension='html')).xml() if len(q) > 0: addl = [] for svcinfo in q: addl.append(TR(TD(svcinfo.f_name), TD(svcinfo.f_text))) atxt['2'] = TABLE(THEAD(TR(TH(T('Name')), TH(T('Text')))), TBODY(addl), _class="table table-condensed table-striped", _style="width:100%").xml() else: atxt['2'] = '' host_rec = db.t_hosts[r.t_services.f_hosts_id] atxt['3'] = host_a_maker(host_rec).xml(), atxt['4'] = r.t_services.f_proto # Append A tags around services with HTTP Ports if r.t_services.f_number in HTTP_PORTS and r.t_services.f_proto == "tcp" or r.t_services.f_name == "HTTP": atxt['5'] = A(r.t_services.f_number, _href=URL('default', 'redirect', extension='html', vars={'url': "http://%s:%s/" % (host_rec.f_ipaddr, r.t_services.f_number)}), _target="%s-tcp-%s" % (host_rec.f_ipaddr, r.t_services.f_number)).xml() elif r.t_services.f_number in HTTPS_PORTS and r.t_services.f_proto == "tcp" or r.t_services.f_name == "HTTPS": atxt['5'] = A(r.t_services.f_number, _href=URL('default', 'redirect', extension='html', vars={'url': "https://%s:%s/" % (host_rec.f_ipaddr, r.t_services.f_number)}), _target="%s-tcp-%s" % (host_rec.f_ipaddr, r.t_services.f_number)).xml() else: atxt['5'] = r.t_services.f_number atxt['6'] = r.t_services.f_status atxt['7'] = len(vulnlist) vulntxt = [] for vuln in vulnlist: color = severity_mapping(vuln[1])[2] vulntxt.append(A(vuln[0], _id="vuln", _target="vulninfo_by_vulnid_%s" % (vuln[0]), _href=URL('vulns', 'vulninfo_by_vulnid', args=[vuln[0]], extension='html'), _style="color:"+color).xml()) atxt['8'] = " :: ".join(vulntxt) if len(explist) > 0: atxt['9'] = "Yes (%d)" % (len(explist)) else: atxt['9'] = '' if len(explist) > 0: atxt['10'] = TABLE(THEAD(TR(TH(T('Name')), TH(T('Title')), TH(T('Source')), TH(T('Rank')))), TBODY(explist), _class="table table-condensed", _style="width:100%").xml() else: atxt['10'] = '' atxt['11'] = r.t_services.f_name atxt['12'] = r.t_services.f_banner atxt['DT_RowId'] = r.t_services.id aaData.append(atxt) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': db(db.t_services).count(), 'iTotalDisplayRecords': nolimit, 'aaData': aaData, } return result else: add = AddModal( db.t_services, 'Add', 'Add', 'Add Service', #fields=[ # 'f_proto', 'f_number', 'f_status', 'f_name', 'f_banner' #], cmd='servicetable.fnReloadAjax();' ) db.t_services.id.comment = add.create() return dict(add=add)
def list(): """ Returns a list of evidence based on a host (id, ipv4, ipv6) or all """ import os, string if request.args(0) is not None: record = get_host_record(request.args(0)) if record is None: redirect(URL('default', 'error', vars={'msg': T('Host record not found')})) response.title = "%s :: Evidence for host %s" % (settings.title, host_title_maker(record)) else: response.title = "%s :: Evidence listing" % (settings.title) record = None aaData = [] if request.extension == "json": if record is None: rows = db(db.t_evidence).select(db.t_evidence.id, db.t_evidence.f_hosts_id, db.t_evidence.f_type, db.t_evidence.f_other_type, db.t_evidence.f_text, db.t_evidence.f_filename, db.t_evidence.f_evidence, db.t_evidence.f_data.len()+1) else: rows = db(db.t_evidence.f_hosts_id == record.id).select(db.t_evidence.id, db.t_evidence.f_hosts_id, db.t_evidence.f_type, db.t_evidence.f_other_type, db.t_evidence.f_text, db.t_evidence.f_filename, db.t_evidence.f_evidence, db.t_evidence.f_data.len()+1) for r in rows: atxt = {} cnt = 0 atxt[cnt] = A('edit', _target="evidence_edit_%s" % (r.t_evidence.id), _href=URL('edit', extension='html', args=r.t_evidence.id)).xml() cnt += 1 if record is None: atxt[cnt] = host_a_maker(r.t_evidence.f_hosts_id).xml() cnt += 1 if r.t_evidence.f_other_type: atxt[cnt] = "Other: %s" % (r.t_evidence.f_other_type) else: atxt[cnt] = r.t_evidence.f_type cnt += 1 atxt[cnt] = r.t_evidence.f_text cnt += 1 if r.t_evidence.f_filename is not None: if string.lower(os.path.splitext(r.t_evidence.f_filename)[1]) in ('.png', '.jpeg', '.jpg', '.gif'): atxt[cnt] = A(IMG(_src=URL('download', args=[r.t_evidence.f_evidence]), _width="50%", _height="20%"), _href=URL('download', args=[r.t_evidence.f_evidence]), _target="evidence_image_%s" % (r.t_evidence.id), _id="evidence_image").xml() cnt += 1 atxt[cnt] = "%sb" % (r._extra['(LENGTH(t_evidence.f_data) + 1)']) cnt += 1 else: atxt[cnt] = A(r.t_evidence.f_filename, _target="evidence_other_%s" % (r.t_evidence.id), _id="evidence_other", _href=URL('download', args=[r.t_evidence.f_evidence])).xml() cnt += 1 atxt[cnt] = "%sb" % (r._extra['(LENGTH(t_evidence.f_data) + 1)']) cnt += 1 else: atxt[cnt] = r.t_evidence.f_filename cnt += 1 atxt['DT_RowId'] = r.t_evidence.id aaData.append(atxt) return { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } if record: th_rows = (TH(T(''), _width="5%"), TH(T('Type')), TH(T('Text')), TH(T('Evidence')), TH(T('File Size')), ) else: th_rows = (TH(T(''), _width="5%"), TH(T('Host')), TH(T('Type')), TH(T('Text')), TH(T('Evidence'), _width="35%"), TH(T('File Size')), ) evidence = TABLE(THEAD(TR(th_rows)), _class="datatable", _id="evidencetable", _style="width:100%") return dict(evidence=evidence, host=record)