def service_vulns_add(): if request.vars.has_key('service'): svc = db.t_services[request.vars.service] or redirect(URL('default', 'error', vars={'msg': T('Service record not found')})) svc_id = [svc.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[svc.f_hosts_id]), svc.f_proto, svc.f_number)] else: svc_id = None if request.vars.has_key('host'): # grab services for a host host_id = db.t_hosts[request.vars.host] or redirect(URL('default', 'error', vars={'msg': T('Host record not found')})) services = db(db.t_services.f_hosts_id == host_id.id).select() 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)]) else: host_id = None if svc_id or host_id: if svc_id: db.t_service_vulns.f_services_id.default = svc_id response.title = "%s :: Add Service Vulnerablity :: %s" % (settings.title, svc) else: db.t_service_vulns.f_services_id.requires = IS_IN_SET(svc_set) response.title = "%s :: Add Service Vulnerablity :: %s" % (settings.title, host_title_maker(db.t_hosts[svc.f_hosts_id])) form=crud.create(db.t_service_vulns,message='Vulnerability added',next=URL('service_vulns_add', vars={'id': svc.id})) db.t_service_vulns.f_services_id.requires = None response.title = "%s :: Add Service Vulnerablity :: %s" % (settings.title, host_title_maker(db.t_hosts[svc.f_hosts_id])) else: form=crud.create(db.t_service_vulns,next='service_vulns_edit/[id]') response.title = "%s :: Add Service Vulnerablity" % (settings.title) return dict(form=form)
def edit(): record = db.t_accounts(request.args(0)) or redirect(URL('default', 'error', vars={'msg': T('Account record not found')})) service = db(db.t_services.id == record.f_services_id).select().first() services = db(db.t_services.f_hosts_id == service.f_hosts_id).select() 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) form=crud.update(db.t_accounts,record,next='edit/[id]', ondelete=lambda form: redirect(URL('list'))) db.t_accounts.f_services_id.requires = None hosttitle = "%s :: %s/%s" % (host_title_maker(db.t_hosts[service.f_hosts_id]), service.f_proto, service.f_number) response.title = "%s :: Update Account :: %s :: %s" % (settings.title, record.f_username, hosttitle) return dict(form=form)
def service_vulns_add(): if request.vars.has_key('service'): svc = db.t_services[request.vars.service] or redirect( URL('default', 'error', vars={'msg': T('Service record not found')})) svc_id = [ svc.id, "%s :: %s/%s" % (host_title_maker( db.t_hosts[svc.f_hosts_id]), svc.f_proto, svc.f_number) ] else: svc_id = None if request.vars.has_key('host'): # grab services for a host host_id = db.t_hosts[request.vars.host] or redirect( URL('default', 'error', vars={'msg': T('Host record not found')})) services = db(db.t_services.f_hosts_id == host_id.id).select() 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) ]) else: host_id = None if svc_id or host_id: if svc_id: db.t_service_vulns.f_services_id.default = svc_id response.title = "%s :: Add Service Vulnerability :: %s" % ( settings.title, svc) else: db.t_service_vulns.f_services_id.requires = IS_IN_SET(svc_set) response.title = "%s :: Add Service Vulnerability :: %s" % ( settings.title, host_title_maker(db.t_hosts[svc.f_hosts_id])) form = crud.create(db.t_service_vulns, message='Vulnerability added', next=URL('service_vulns_add', vars={'id': svc.id})) db.t_service_vulns.f_services_id.requires = None response.title = "%s :: Add Service Vulnerability :: %s" % ( settings.title, host_title_maker(db.t_hosts[svc.f_hosts_id])) else: form = crud.create(db.t_service_vulns, next='service_vulns_edit/[id]') response.title = "%s :: Add Service Vulnerability" % (settings.title) return dict(form=form)
def edit(): record = db.t_evidence(request.args(0)) or redirect( URL("default", "error", vars={"msg": T("Evidence record not found")}) ) response.title = "%s :: Evidence Update :: %s" % (settings.title, host_title_maker(db.t_hosts[record.f_hosts_id])) form = crud.update(db.t_evidence, record, next="edit/[id]", ondelete=lambda form: redirect(URL("list"))) return dict(form=form)
def add(): if request.vars.has_key('id'): host_id = db.t_hosts[request.vars.id] or redirect( URL('default', 'error', vars={'msg': T('Host record not found')})) else: host_id = None if host_id: # grab services for a host services = db(db.t_services.f_hosts_id == host_id.id).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) form = crud.create(db.t_accounts, message='Account added', next=URL('accounts_create', vars={'id': host_id.id})) db.t_accounts.f_services_id.requires = None else: form = crud.create(db.t_accounts, next='edit/[id]', message="Account added") cache.ram.clear('accounts_list') response.title = "%s :: Add Account" % (settings.title) return dict(form=form)
def read(): record = db.t_snmp(request.args(0)) or redirect( URL('default', 'error', vars={'msg': T('SNMP record not found')})) response.title = "%s :: SNMP :: %s" % ( settings.title, host_title_maker(db.t_hosts[record.f_hosts_id])) form = crud.read(db.t_snmp, record) return dict(form=form)
def edit(): record = db.t_host_notes(request.args(0)) or redirect( URL('default', 'error', vars={'msg': T('Note record not found')})) response.title = "%s :: Update Host Note :: %s" % ( settings.title, host_title_maker(db.t_hosts[record.f_hosts_id])) form = crud.update(db.t_host_notes, record, next='edit/[id]', ondelete=lambda form: redirect(URL('list'))) return dict(form=form)
def refs_edit(): record = db.t_host_os_refs(request.args(0)) or redirect( URL('default', 'error', vars={'msg': T('OS Reference record not found')})) form = crud.update(db.t_host_os_refs, record, next='refs_edit/[id]', ondelete=lambda form: redirect(URL('refs_list'))) response.title = "%s :: OS for Host %s" % ( settings.title, host_title_maker(db.t_hosts(record.f_hosts_id))) return dict(form=form)
def by_host(): """ Returns a list of OS records based upon an host identifier (id, ipv4, ipv6) """ if request.args(0) is None: redirect(URL('default', 'error', vars={'msg': T('Host record not found')})) 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 :: SNMP Records for %s" % (settings.title, host_title_maker(record)) snmplist = db(db.t_snmp.f_hosts_id==record.id).select() aaData = [] if request.extension == "json": for snmp in snmplist: # datatables json requires aaData to be specificly formatted aaData.append({ '0': A("edit", _target="snmp_update_%s" % (snmp.id), _href=URL('edit',extension='html',args=snmp.id)).xml(), '1': snmp.f_community, '2': snmp.f_version, '3': snmp.f_access, 'DT_RowId': snmp.id, }) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result form = TABLE(THEAD(TR(TH(T('ID'), _width="5%"), TH(T('Community')), TH(T('Version')), TH(T('Access')), ) ), _class="datatable", _id="snmptable", _style="width:100%") add = AddModal( db.t_snmp, 'Add', 'Add', 'Add SNMP String', fields=[ 'f_community', 'f_version', 'f_access'], cmd='snmptable.fnReloadAjax();' ) db.t_snmp.f_hosts_id.default = record.id db.t_snmp.id.comment = add.create() return dict(form=form, host=record, add=add)
def summary_by_host(): """ Returns a list of notes records based upon an host identifier (id, ipv4, ipv6) """ if request.args(0) is None: redirect( URL('default', 'error', vars={'msg': T('No host record provided')})) 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 :: Notes for host %s" % (settings.title, host_title_maker(record)) rows = db(db.t_host_notes.f_hosts_id == record.id)(db.t_host_notes).select( db.t_host_notes.id, db.t_host_notes.f_note) aaData = [] if request.extension == "json": for r in rows: # datatables json requires aaData to be specificly formatted atxt = [] atxt.append('<a href="javascript:void()" onclick="delnotes_summ(' + str(r.id) + ')">X</a>') atxt.append(r.f_note) # add columns after this, don't do anything prior since it'll affect the hidden fields aaData.append(atxt) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result notes = TABLE(THEAD(TR( TH(T('[X]'), _width="5%"), TH(T('Note'), _width="90%"), ), _style="display:none"), _class="table table-condensed", _id="notestable_summary", _style="width:100%") return dict(notes=notes)
def add(): if request.vars.has_key('id'): host_id = db.t_hosts[request.vars.id] or redirect(URL('default', 'error', vars={'msg': T('Host record not found')})) else: host_id = None if host_id: # grab services for a host services = db(db.t_services.f_hosts_id == host_id.id).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) form=crud.create(db.t_accounts,message='Account added',next=URL('accounts_create', vars={'id': host_id.id})) db.t_accounts.f_services_id.requires = None else: form=crud.create(db.t_accounts, next='edit/[id]',message="Account added") cache.ram.clear('accounts_list') response.title = "%s :: Add Account" % (settings.title) return dict(form=form)
def summary_by_host(): """ Returns a list of notes records based upon an host identifier (id, ipv4, ipv6) """ if request.args(0) is None: redirect(URL('default', 'error', vars={'msg': T('No host record provided')})) 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 :: Notes for host %s" % (settings.title, host_title_maker(record)) rows = db(db.t_host_notes.f_hosts_id == record.id)(db.t_host_notes).select(db.t_host_notes.id, db.t_host_notes.f_note) aaData = [] if request.extension == "json": for r in rows: # datatables json requires aaData to be specificly formatted atxt = [] atxt.append('<a href="javascript:void()" onclick="delnotes_summ(' + str(r.id) +')">X</a>') atxt.append(r.f_note) # add columns after this, don't do anything prior since it'll affect the hidden fields aaData.append(atxt) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result notes = TABLE(THEAD(TR(TH(T('[X]'), _width="5%"), TH(T('Note'), _width="90%"), ), _style="display:none" ), _class="table table-condensed", _id="notestable_summary", _style="width:100%") return dict(notes=notes)
def popover(): """ Returns the detail of a host for popovers """ host_rec = get_host_record(request.args(0)) resp = {} if not host_rec: resp['title'] = "Host not found" resp['content'] = "" else: svcs = host_rec.t_services svc_cnt = 0 vuln_cnt = 0 acct_cnt = 0 for svc in svcs.select(): svc_cnt += 1 vuln_cnt += svc.t_service_vulns.count() acct_cnt += svc.t_accounts.count() host_os = (0, 'Unknown') for os_rec in host_rec.t_host_os_refs.select(): if os_rec.f_certainty > host_os[0]: host_os = (os_rec.f_certainty, db.t_os[os_rec.f_os_id].f_title) resp['title'] = host_title_maker(host_rec) resp['content'] = XML( TABLE( TR(TD(T('Asset Group')), TD(host_rec.f_asset_group)), TR(TD(T('Engineer')), TD(db.auth_user[host_rec.f_engineer].username)), TR(TD(T('OS')), TD("%s (%s)" % (host_os[1], host_os[0]))), TR(TD(T('Services')), TD(svc_cnt), _class="success"), TR(TD(T('Vulnerabilities')), TD(vuln_cnt), _class="error"), TR(TD(T('Accounts')), TD(acct_cnt), _class="warning"), _class="table table-condensed", )) return resp
def popover(): """ Returns the detail of a host for popovers """ host_rec = get_host_record(request.args(0)) resp = {} if not host_rec: resp['title'] = "Host not found" resp['content'] = "" else: svcs = host_rec.t_services svc_cnt = 0 vuln_cnt = 0 acct_cnt = 0 for svc in svcs.select(): svc_cnt += 1 vuln_cnt += svc.t_service_vulns.count() acct_cnt += svc.t_accounts.count() host_os = (0, 'Unknown') for os_rec in host_rec.t_host_os_refs.select(): if os_rec.f_certainty > host_os[0]: host_os = (os_rec.f_certainty, db.t_os[os_rec.f_os_id].f_title) resp['title'] = host_title_maker(host_rec) resp['content'] = XML(TABLE( TR(TD(T('Asset Group')), TD(host_rec.f_asset_group)), TR(TD(T('Engineer')), TD(db.auth_user[host_rec.f_engineer].username)), TR(TD(T('OS')), TD("%s (%s)" % (host_os[1], host_os[0]))), TR(TD(T('Services')), TD(svc_cnt), _class="success"), TR(TD(T('Vulnerabilities')), TD(vuln_cnt), _class="error"), TR(TD(T('Accounts')), TD(acct_cnt), _class="warning"), _class="table table-condensed", )) return resp
Field('id','id', represent=lambda i, row:SPAN(A(i,_id="host_detail_%s" % (i),_href=URL('hosts', 'detail',args=i)))), Field('f_ipv4', type='string', length=15, unique=True, requires=IS_EMPTY_OR(IS_IPV4()), label=T('IPv4 Address')), Field('f_ipv6', type='string', label=T('IPv6 Address'), requires=IS_EMPTY_OR(IS_IPV6())), Field('f_macaddr', type='string', label=T('MAC Address')), Field('f_hostname', type='string', label=T('Hostname')), Field('f_netbios_name', type='string', label=T('NetBIOS Name')), Field('f_confirmed', type='boolean', default=False, label=T('Confirmed')), Field('f_accessed', type='boolean', default=False, label=T('Accessed'), comment=T('Host has been accessed by an Engineer')), Field('f_followup', type='boolean', label=T('Follow Up')), Field('f_engineer', type='reference auth_user', label=T('Engineer')), Field('f_asset_group', type='string', label=T('Asset Group'), widget=autocomplete_bootstrap, requires=IS_NOT_EMPTY()), Field('f_service_count', type='integer', default=0, label=T('Service Count')), Field('f_vuln_count', type='integer', default=0, label=T('Vuln Count')), Field('f_vuln_graph', type='string', default='0,0,0,0,0,0,0,0,0,0', label=T('Vuln Graph')), Field('f_exploit_count', type='integer', default=0, label=T('Exploit Count')), format=lambda r: host_title_maker(r), fake_migrate=settings.fake_migrate, migrate=settings.migrate) ######################################## ## Customer operating system records ## These SHOULD be copied from CPE but ## if not they'll be flagged as such. db.define_table('t_os', Field('id','id', represent=lambda id,row:SPAN(A(id,_href=URL('os', 'os_edit',args=id)))), Field('f_cpename', length=255, type='string', label=T('CPE Name'), unique=False), Field('f_title', type='string', label=T('Title'), requires=IS_NOT_EMPTY()), Field('f_vendor', type='string', label=T('Vendor'), widget=autocomplete_bootstrap, requires=IS_NOT_EMPTY()), Field('f_product', type='string', label=T('Product'), widget=autocomplete_bootstrap, requires=IS_NOT_EMPTY()), Field('f_version', type='string', label=T('Version')), Field('f_update', type='string', label=T('Update')), Field('f_edition', type='string', label=T('Edition')),
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 paste(): """ Import and parse password pasted to a textbox into t_accounts """ from skaldship.general import check_datadir check_datadir(request.folder) # Service_id is primary, host_id is secondary, if none then list # all the services svc_set = [] url=URL('accounts', 'paste') if request.vars.has_key('service_id'): try: record = db.t_services[request.vars.service_id] svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) url = URL('accounts', 'paste', vars={'service_id':request.vars.service_id}) except: pass elif request.vars.has_key('host_id'): try: host_record = get_host_record(request.vars.host_id) svc_records = db(db.t_services.f_hosts_id == host_record.id).select(cache=(cache.ram, 30)) url = URL('accounts', 'paste', vars={'host_id':request.vars.host_id}) for record in svc_records: svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) except: pass if len(svc_set) == 0: # all services svc_records = db(db.t_services).select(cache=(cache.ram,30)) svc_set = [] for record in svc_records: svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) if request.extension == "load": buttons=[] else: buttons=['submit'] form = SQLFORM.factory( Field('f_service', 'string', label=T('Host / Service'), requires=IS_IN_SET(svc_set), default=svc_set[0][0]), Field('f_pwtext', 'text', label=T('Password text')), Field('f_type', 'string', label=T('File type'), default='PWDUMP', requires=IS_IN_SET(settings.password_file_types)), Field('f_source', 'string', label=T('Source (if necessary)')), Field('f_add_to_evidence', 'boolean', label=T('Add file to Evidence')), buttons=buttons, _action=url, _id='accounts_paste_form' #_action=url, _id='accounts_paste_form', formstyle='bootstrap_modal' ) resp_text = "" accounts_added = [] accounts_updated = [] if form.errors: response.flash = 'Error in form' return TABLE(*[TR(k, v) for k, v in form.errors.items()]) elif form.accepts(request.vars, session): from gluon.utils import web2py_uuid host_id = db.t_services[form.vars.f_service].f_hosts_id pwd_file_dir = os.path.join(request.folder, 'data', 'passwords', 'other') if not os.path.exists(pwd_file_dir): from gluon.fileutils import mktree mktree(pwd_file_dir) filename = "%s-pwfile-%s" % (host_id, web2py_uuid()) full_file_path = os.path.join(request.folder, 'data/passwords/other', filename) of = open(full_file_path, "w") of.write(form.vars.f_pwtext) of.close() logger.debug("Processing password file: %s" % (full_file_path)) account_data = process_password_file(pw_file=full_file_path, file_type=request.vars.f_type, source=request.vars.f_source) response.headers['web2py-component-command'] = 'accounttable.fnReloadAjax();' resp_text = insert_or_update_acct(form.vars.f_service, account_data) if form.vars.f_add_to_evidence is True: # add the password file to evidence try: pwdata = open(full_file_path, "r").readlines() except Exception, e: logger.error("Error opening %s: %s" % (full_file_path, e)) resp_text += "Error opening %s: %s\n" % (full_file_path, e) db.t_evidence.insert( f_hosts_id = host_id, f_type = 'Password File', f_text = form.vars.f_type, f_filename = filename, f_evidence = filename, f_data = pwdata) resp_text += "\n%s added to evidence\n" % (filename) db.commit()
def paste(): """ Import and parse password pasted to a textbox into t_accounts """ from skaldship.general import check_datadir check_datadir(request.folder) # Service_id is primary, host_id is secondary, if none then list # all the services svc_set = [] url = URL('accounts', 'paste') if request.vars.has_key('service_id'): try: record = db.t_services[request.vars.service_id] svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) url = URL('accounts', 'paste', vars={'service_id': request.vars.service_id}) except: pass elif request.vars.has_key('host_id'): try: host_record = get_host_record(request.vars.host_id) svc_records = db( db.t_services.f_hosts_id == host_record.id).select( cache=(cache.ram, 30)) url = URL('accounts', 'paste', vars={'host_id': request.vars.host_id}) for record in svc_records: svc_set.append( (record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) except: pass if len(svc_set) == 0: # all services svc_records = db(db.t_services).select(cache=(cache.ram, 30)) svc_set = [] for record in svc_records: svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) if request.extension == "load": buttons = [] else: buttons = ['submit'] form = SQLFORM.factory( Field('f_service', 'string', label=T('Host / Service'), requires=IS_IN_SET(svc_set), default=svc_set[0][0]), Field('f_pwtext', 'text', label=T('Password text')), Field('f_type', 'string', label=T('File type'), default='PWDUMP', requires=IS_IN_SET(settings.password_file_types)), Field('f_source', 'string', label=T('Source (if necessary)')), Field('f_add_to_evidence', 'boolean', label=T('Add file to Evidence')), buttons=buttons, _action=url, _id='accounts_paste_form' #_action=url, _id='accounts_paste_form', formstyle='bootstrap_modal' ) resp_text = "" accounts_added = [] accounts_updated = [] if form.errors: response.flash = 'Error in form' return TABLE(*[TR(k, v) for k, v in form.errors.items()]) elif form.accepts(request.vars, session): from gluon.utils import web2py_uuid host_id = db.t_services[form.vars.f_service].f_hosts_id pwd_file_dir = os.path.join(request.folder, 'data', 'passwords', 'other') if not os.path.exists(pwd_file_dir): from gluon.fileutils import mktree mktree(pwd_file_dir) filename = "%s-pwfile-%s" % (host_id, web2py_uuid()) full_file_path = os.path.join(request.folder, 'data/passwords/other', filename) of = open(full_file_path, "w") of.write(form.vars.f_pwtext) of.close() logger.debug("Processing password file: %s" % (full_file_path)) account_data = process_password_file(pw_file=full_file_path, file_type=request.vars.f_type, source=request.vars.f_source) response.headers[ 'web2py-component-command'] = 'accounttable.fnReloadAjax();' resp_text = insert_or_update_acct(form.vars.f_service, account_data) if form.vars.f_add_to_evidence is True: # add the password file to evidence try: pwdata = open(full_file_path, "r").readlines() except Exception, e: logger.error("Error opening %s: %s" % (full_file_path, e)) resp_text += "Error opening %s: %s\n" % (full_file_path, e) db.t_evidence.insert(f_hosts_id=host_id, f_type='Password File', f_text=form.vars.f_type, f_filename=filename, f_evidence=filename, f_data=pwdata) resp_text += "\n%s added to evidence\n" % (filename) db.commit()
def by_host(): """ Returns a list of services + serviceinfo based upon an host identifier (id, ipaddr) """ 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 :: Accounts for %s" % (settings.title, host_title_maker(record)) query = (db.t_services.f_hosts_id == record.id) if request.extension == "json": aaData = [] rows = db(query).select( db.t_accounts.ALL, db.t_services.ALL, left=db.t_services.on( db.t_accounts.f_services_id == db.t_services.id)) for r in rows: if r.t_accounts.f_compromised == True: comprdiv = '<div class="acct_compromised" name="row_id" id="%s"><span class="icon-check"></span></div>' % r.t_accounts.id else: comprdiv = '<div class="acct_uncompromised" name="row_id" id="%s"/>' % r.t_accounts.id aaData.append({ '0': A("edit", _target="accounts_update_%s" % (r.t_accounts.id), _href=URL('accounts', 'edit', args=[r.t_accounts.id], extension='html')).xml(), '1': comprdiv, '2': A("%s/%s" % (r.t_services.f_proto, r.t_services.f_number), _target="services_edit_%s" % (r.t_services.id), _href=URL('services', 'edit', args=[r.t_services.id], extension='html')).xml(), '3': A(r.t_accounts.f_username, _target="accounts_username_%s" % (r.t_accounts.f_username), _href=URL('accounts', 'by_username', vars={'username': r.t_accounts.f_username}, extension='html')).xml(), '4': r.t_accounts.f_fullname, '5': r.t_accounts.f_password, '6': r.t_accounts.f_hash1_type, '7': r.t_accounts.f_hash1, '8': r.t_accounts.f_hash2_type, '9': r.t_accounts.f_hash2, '10': r.t_accounts.f_uid, '11': r.t_accounts.f_gid, '12': r.t_accounts.f_lockout, '13': r.t_accounts.f_duration, '14': r.t_accounts.f_source, '15': r.t_accounts.f_level, '16': r.t_accounts.f_description, 'DT_RowId': r.t_accounts.id, }) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result form = TABLE(THEAD( TR( TH(T(''), _width="5%"), TH(T('Compr'), _width="5%"), TH(T('Port')), TH(T('Username')), TH(T('Fullname')), 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('Lockout')), TH(T('Duration')), TH(T('Source')), TH(T('Level')), 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 == record.id).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, host=record, 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 edit(): record = db.t_host_notes(request.args(0)) or redirect(URL('default', 'error', vars={'msg': T('Note record not found')})) response.title = "%s :: Update Host Note :: %s" % (settings.title, host_title_maker(db.t_hosts[record.f_hosts_id])) form=crud.update(db.t_host_notes,record,next='edit/[id]', ondelete=lambda form: redirect(URL('list'))) return dict(form=form)
def refs_edit(): record = db.t_host_os_refs(request.args(0)) or redirect(URL('default', 'error', vars={'msg': T('OS Reference record not found')})) form=crud.update(db.t_host_os_refs,record,next='refs_edit/[id]', ondelete=lambda form: redirect(URL('refs_list'))) response.title = "%s :: OS for Host %s" % (settings.title, host_title_maker(db.t_hosts(record.f_hosts_id))) return dict(form=form)
def detail(): if request.args(0) is None: redirect(URL('default', 'error', vars={'msg': T('Host record not found')})) response.files.append(URL(request.application,'static','js/jquery.sparkline.js')) response.files.append(URL(request.application,'static','jstree/jstree.min.js')) #query = db.t_hosts.id == request.args(0) #query = create_hostfilter_query(session.hostfilter, query) record = get_host_record(request.args(0)) if record is None: redirect(URL('hosts', 'list')) hostipv4=record.f_ipv4 engineername = db.auth_user[record.f_engineer].username # to allow updating of the host record from this page host=crud.read(db.t_hosts,record) host.attributes['_id'] = "host_record" host_points = {} # build the host_points field which will cover: # the top t_host_os_ref cpe string os_list = db(db.t_host_os_refs.f_hosts_id == record.id).select() host_points['os'] = (0, 'Unknown') for os_rec in os_list: if os_rec.f_certainty > host_points['os'][0]: host_points['os'] = (os_rec.f_certainty, db.t_os[os_rec.f_os_id].f_title) host_points['account_cnt'] = 0 host_points['password_cnt'] = 0 host_points['cracked_pct'] = 0 host_points['vuln_cnt'] = 0 host_points['vuln_exploited_cnt'] = 0 host_points['vuln_potential_cnt'] = 0 vulns = {} vuln_list = [] services = db(db.t_services.f_hosts_id == record.id).select() for svc in services: for vuln in db(db.t_service_vulns.f_services_id == svc.id).select(): vulndata = db.t_vulndata[vuln.f_vulndata_id] vulns[vulndata.f_vulnid] = ( vulndata.f_severity, vulndata.f_cvss_score ) vuln_list.append(vulndata) host_points['vuln_exploited_cnt'] += db((db.t_service_vulns.f_services_id==svc.id) & (db.t_service_vulns.f_status.like('%exploited%'))).count() host_points['vuln_potential_cnt'] += db((db.t_service_vulns.f_services_id==svc.id) & (db.t_service_vulns.f_status.like('%potential%'))).count() host_points['vuln_cnt'] += db(db.t_service_vulns.f_services_id==svc.id).count() host_points['account_cnt'] += db(db.t_accounts.f_services_id==svc.id).count() pwq = ((db.t_accounts.f_services_id==svc.id) & (db.t_accounts.f_compromised == True)) #pwq &= (((db.t_accounts.f_password != None) | (db.t_accounts.f_password != '')) | (db.t_accounts.f_compromised == True)) host_points['password_cnt'] += db(pwq).count() try: host_points['cracked_pct'] = 100 * (host_points['password_cnt'] / host_points['account_cnt']) except ZeroDivisionError: host_points['cracked_pct'] = 0 # breakdown of vuln severity sev_sum_dict = {} for a in range(1, 11): sev_sum_dict[a] = 0 for k,v in vulns.iteritems(): # take the severity and increment the sev_sum set item if settings.use_cvss: severity = int(float(v[1])) else: severity = v[0] count = sev_sum_dict.setdefault(severity, 1) count += 1 sev_sum_dict[severity] = count sev_sum_spark = [] sev_sum = [] for k,v in sev_sum_dict.iteritems(): sev_sum_spark.append(str(v)) if v > 0: sev_sum.append("%s: %s" % (k, v)) host_points['sev_sum_spark'] = ",".join(sev_sum_spark) host_points['sev_sum'] = " / ".join(sev_sum) # netbios record (or none if it's empty) netb_record = db(db.t_netbios.f_hosts_id == record.id).select().first() or None if netb_record is not None: netbios=crud.update(db.t_netbios, netb_record, ondelete=lambda netbios: redirect(URL('host_detail', args=[ record.id ]))) host_points['netb_domain'] = netb_record.f_domain host_points['netb_type'] = netb_record.f_type else: db.t_netbios.f_hosts_id.default = record.id netbios = LOAD('netbios', 'add.load', args=[host.record.id], ajax=True, target='netbios_info') host_pagination = pagination(request, record) response.title = "%s :: Host info :: %s" % (settings.title, host_title_maker(record)) return dict(host=host, netbios=netbios, host_points=host_points, host_pagination=host_pagination, hostipv4=hostipv4, engineername=engineername)
def import_file(): """ Import and parse password file into t_accounts """ import os from skaldship.general import check_datadir check_datadir(request.folder) # Service_id is primary, host_id is secondary, if none then list # all the services svc_set = [] url = URL('accounts', 'import_file') if request.vars.has_key('service_id'): try: record = db.t_services[request.vars.service_id] svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) url = URL('accounts', 'import_file', vars={'service_id': request.vars.service_id}) except: pass elif request.vars.has_key('host_id'): try: host_record = get_host_record(request.vars.host_id) svc_records = db( db.t_services.f_hosts_id == host_record.id).select( cache=(cache.ram, 30)) url = URL('accounts', 'import_file', vars={'host_id': request.vars.host_id}) for record in svc_records: svc_set.append( (record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) except: pass if len(svc_set) == 0: # all services svc_records = db(db.t_services).select(cache=(cache.ram, 30)) svc_set = [] for record in svc_records: svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) if request.extension == "load": buttons = [] else: buttons = ['submit'] form = SQLFORM.factory( Field('f_service', 'string', label=T('Host / Service'), requires=IS_IN_SET(svc_set), default=svc_set[0][0]), Field('f_filename', 'upload', uploadfolder=os.path.join(request.folder, settings.password_upload_dir), label=T('Password file')), Field('f_type', 'string', label=T('File type'), default='PWDUMP', requires=IS_IN_SET(settings.password_file_types)), Field('f_source', 'string', label=T('Source (if necessary)')), Field('f_add_to_evidence', 'boolean', label=T('Add Evidence')), Field('f_taskit', type='boolean', default=True, label=T('Run in background task')), buttons=buttons, _action=url, _id='accounts_import_form') resp_text = "" accounts_added = [] accounts_updated = [] if form.errors: response.flash = 'Error in form' return TABLE(*[TR(k, v) for k, v in form.errors.items()]) elif form.accepts(request.vars, session): if form.vars.f_filename is not None: orig_filename = request.vars.f_filename.filename filename = os.path.join(request.folder, settings.password_upload_dir, form.vars.f_filename) if form.vars.f_taskit: task = scheduler.queue_task( accounts_import_file, pvars=dict(filename=filename, service=form.vars.f_service, f_type=form.vars.f_type, f_source=form.vars.f_source), group_name=settings.scheduler_group_name, sync_output=5, timeout=settings.scheduler_timeout) if task.id: resp_text = "Submitted file for processing: %s" % (A( "task " + str(task.id), _href=URL(c='tasks', f='status', args=task.id)).xml()) else: resp_text = "Error submitting job: %s" % (task.errors) else: logger.info("Processing password file: %s" % (filename)) account_data = process_password_file(pw_file=filename, file_type=request.vars.f_type, source=request.vars.f_source) resp_text = insert_or_update_acct(form.vars.f_service, account_data) logger.info(resp_text) if form.vars.f_add_to_evidence is True: # add the password file to evidence try: pwdata = open(filename, "r").readlines() except Exception, e: logger.error("Error opening %s: %s" % (filename, e)) db.t_evidence.insert( f_hosts_id=db.t_services[form.vars.f_service].f_hosts_id, f_type='Password File', f_text=form.vars.f_type, f_filename=orig_filename, f_evidence=form.vars.f_filename, f_data=pwdata) db.commit()
def by_host(): """ Returns a list of services + serviceinfo based upon an host identifier (id, ipv4, ipv6) """ 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 :: Accounts for %s" % (settings.title, host_title_maker(record)) query = db.t_services.f_hosts_id == record.id if request.extension == "json": aaData = [] rows = db(query).select( db.t_accounts.ALL, db.t_services.ALL, left=db.t_services.on(db.t_accounts.f_services_id == db.t_services.id) ) for r in rows: if r.t_accounts.f_compromised == True: comprdiv = ( '<div class="acct_compromised" name="row_id" id="%s"><span class="icon-check"></span></div>' % r.t_accounts.id ) else: comprdiv = '<div class="acct_uncompromised" name="row_id" id="%s"/>' % r.t_accounts.id aaData.append( { "0": A( "edit", _target="accounts_update_%s" % (r.t_accounts.id), _href=URL("accounts", "edit", args=[r.t_accounts.id], extension="html"), ).xml(), "1": comprdiv, "2": A( "%s/%s" % (r.t_services.f_proto, r.t_services.f_number), _target="services_edit_%s" % (r.t_services.id), _href=URL("services", "edit", args=[r.t_services.id], extension="html"), ).xml(), "3": A( r.t_accounts.f_username, _target="accounts_username_%s" % (r.t_accounts.f_username), _href=URL( "accounts", "by_username", vars={"username": r.t_accounts.f_username}, extension="html" ), ).xml(), "4": r.t_accounts.f_fullname, "5": r.t_accounts.f_password, "6": r.t_accounts.f_hash1_type, "7": r.t_accounts.f_hash1, "8": r.t_accounts.f_hash2_type, "9": r.t_accounts.f_hash2, "10": r.t_accounts.f_uid, "11": r.t_accounts.f_gid, "12": r.t_accounts.f_lockout, "13": r.t_accounts.f_duration, "14": r.t_accounts.f_source, "15": r.t_accounts.f_level, "16": r.t_accounts.f_description, "DT_RowId": r.t_accounts.id, } ) result = {"sEcho": request.vars.sEcho, "iTotalRecords": len(aaData), "aaData": aaData} return result form = TABLE( THEAD( TR( TH(T(""), _width="5%"), TH(T("Compr"), _width="5%"), TH(T("Port")), TH(T("Username")), TH(T("Fullname")), 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("Lockout")), TH(T("Duration")), TH(T("Source")), TH(T("Level")), 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 == record.id).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, host=record, add=add)
def by_username(): if request.vars.get('username', 'None') != 'None': record = None response.title = "%s :: Account entries for %s" % ( settings.title, request.vars.username) query = (db.t_accounts.f_username.like(request.vars.username)) else: query = (db.t_accounts.active) aaData = [] rows = db(query).select( db.t_accounts.ALL, db.t_hosts.ALL, db.t_services.ALL, left=(db.t_services.on( db.t_accounts.f_services_id == db.t_services.id), db.t_hosts.on(db.t_hosts.id == db.t_services.f_hosts_id))) for r in rows: atxt = [] hostrec = db.t_hosts[r.t_hosts.id] atxt.append( TD( A("edit", _target="accounts_update_%s" % (r.t_accounts.id), _href=URL('accounts', 'edit', args=[r.t_accounts.id], extension='html')))) atxt.append( TD(INPUT(_name="id", _value=str(r.t_accounts.id), _type="checkbox"))) atxt.append( TD( A("%s" % (host_title_maker(hostrec)), _target="host_detail_%s" % (r.t_hosts.id), _href=URL('hosts', 'detail', args=[r.t_hosts.id])))) atxt.append( TD( A("%s/%s" % (r.t_services.f_proto, r.t_services.f_number), _target="services_edit_%s" % (r.t_services.id), _href=URL('services', 'edit', args=[r.t_services.id], extension='html')))) atxt.append(TD(r.t_accounts.f_username)) atxt.append(TD(r.t_accounts.f_fullname)) atxt.append(TD(r.t_accounts.f_password)) atxt.append(TD(r.t_accounts.f_compromised)) atxt.append(TD(r.t_accounts.f_hash1_type)) atxt.append(TD(r.t_accounts.f_hash1)) atxt.append(TD(r.t_accounts.f_hash2_type)) atxt.append(TD(r.t_accounts.f_hash2)) atxt.append(TD(r.t_accounts.f_uid)) atxt.append(TD(r.t_accounts.f_gid)) atxt.append(TD(r.t_accounts.f_lockout)) atxt.append(TD(r.t_accounts.f_duration)) atxt.append(TD(r.t_accounts.f_source)) atxt.append(TD(r.t_accounts.f_level)) atxt.append(TD(r.t_accounts.f_description)) aaData.append(TR(atxt)) form = TABLE(THEAD( TR( TH(T('ID'), _width="5%"), TH(T(''), _width="2%"), TH(T('Host')), TH(T('Port')), TH(T('Username')), TH(T('Fullname')), TH(T('Password')), TH(T('Compromised')), 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('Lockout')), TH(T('Duration')), TH(T('Source')), TH(T('Level')), TH(T('Description')), )), TBODY(aaData), _class="datatable", _id="accounttable", _style="width:100%") return dict(form=form)
def by_host(): """ Returns a list of services + serviceinfo based upon an host identifier (id, ipv4, ipv6) """ 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 :: Services for %s" % (settings.title, host_title_maker(record)) services = db(db.t_services.f_hosts_id == record.id).select( db.t_services.id, db.t_services.f_proto, db.t_services.f_number, db.t_services.f_status, db.t_services.f_name, db.t_services.f_banner) #, cache=(cache.ram,60)) svcq = (db.t_services.f_hosts_id == record.id) infoq = (db.t_service_info.f_services_id == db.t_services.id) if request.extension == "json": #rows = db(svcq).select(db.t_services.ALL, db.t_service_info.ALL, left=db.t_service_info.on(infoq)) aaData = [] for svc in services: # service info atxt = {} q = db(db.t_service_info.f_services_id == svc.id).select() if len(q) > 0: addl = [] for svcinfo in q: addl.append(TR(TD(svcinfo.f_name), TD(svcinfo.f_text))) atxt['0'] = IMG(_src=URL(request.application, 'static', 'images/details_open.png')).xml() atxt['1'] = TABLE(THEAD(TR(TH(T('Name')), TH(T('Text')))), TBODY(addl)).xml() else: atxt['0'] = ("") atxt['1'] = ("") atxt['2'] = A('edit', _target="services_edit_%s" % (svc.id), _href=URL('edit', args=[svc['id']], extension='html')).xml() atxt['3'] = svc.f_proto if svc.f_number in HTTP_PORTS and svc.f_proto == "tcp" or svc.f_name == "HTTP": atxt['4'] = A(svc.f_number, _href="http://%s:%s/" % (record.f_ipaddr, svc.f_number), _target="%s-tcp-%s" % (record.f_ipaddr, svc.f_number)).xml() elif svc.f_number in HTTPS_PORTS and svc.f_proto == "tcp" or svc.f_name == "HTTPS": atxt['4'] = A(svc.f_number, _href="https://%s:%s/" % (record.f_ipaddr, svc.f_number), _target="%s-tcp-%s" % (record.f_ipaddr, svc.f_number)).xml() else: atxt['4'] = svc.f_number atxt['5'] = svc.f_status atxt['6'] = svc.f_name or "" atxt['7'] = svc.f_banner or "" atxt['DT_RowId'] = svc.id aaData.append(atxt) result = { 'sEcho': request.vars._, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result 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.f_hosts_id.default = record.id db.t_services.id.comment = add.create() form = TABLE(THEAD( TR( TH('', _width="5%"), TH('Info'), TH(T('')), TH(T('Protocol')), TH(T('Number')), TH(T('Status')), TH(T('Name')), TH(T('Banner')), )), _class="datatable", _id="servicetable", _style="width:100%") return dict(form=form, host=record, add=add)
def purge_data(): # Purges all the data except user tables response.title = "%s :: Database Purge" % (settings.title) users = db(db.auth_user).select() userlist = [] for user in users: userlist.append( [ user.id, user.username ] ) hosts = db(db.t_hosts).select() hostlist = [] for host in hosts: hostlist.append( [ host.id, host_title_maker(host) ] ) ag_rows = db(db.t_hosts).select(db.t_hosts.f_asset_group, distinct=True).as_list() asset_groups = [] for ag in ag_rows: asset_groups.append(ag['f_asset_group']) form = SQLFORM.factory( Field('host', type='list:integer', label=T('Delete a host'), requires=IS_EMPTY_OR(IS_IN_SET(hostlist))), Field('engineer', type='list:integer', label=T('Hosts by user'), requires=IS_EMPTY_OR(IS_IN_SET(userlist))), Field('asset_group', type='string', label=T('Asset Group'), requires=IS_EMPTY_OR(IS_IN_SET(asset_groups))), Field('all_data', type='boolean', label=T('Truncate all tables')), Field('are_you_sure', type='boolean', label=T('Are you sure?'), requires=IS_NOT_EMPTY(error_message='ARE YOU SURE?!?!')), ) if form.accepts(request.vars, session): if not form.vars.are_you_sure: form.errors.are_you_sure = 'ARE YOU SURE?' else: if form.vars.all_data: db.t_hosts.truncate(mode="CASCADE") db.t_services.truncate(mode="CASCADE") db.t_os.truncate(mode="CASCADE") db.t_host_os_refs.truncate(mode="CASCADE") db.t_apps.truncate(mode="CASCADE") db.t_services_apps_refs.truncate(mode="CASCADE") db.t_service_vulns.truncate(mode="CASCADE") db.t_service_info.truncate(mode="CASCADE") db.t_accounts.truncate(mode="CASCADE") db.t_host_notes.truncate(mode="CASCADE") db.t_evidence.truncate(mode="CASCADE") db.t_snmp.truncate(mode="CASCADE") db.commit() response.flash = 'All data purged' elif form.vars.host: host_id = form.vars.host del db.t_hosts[host_id] response.flash = "Host %s purged" % (form.vars.host) elif form.vars.engineer: # TODO: Test this delcnt = db(db.t_hosts.f_engineer == form.vars.engineer).delete() db.commit() response.flash = "Hosts owned by %s purged (%d records)" % (form.vars.engineer, delcnt) elif form.vars.asset_group: delcnt = db(db.t_hosts.f_asset_group == form.vars.asset_group).delete() db.commit() response.flash = "Asset group %s purged (%d records)" % (form.vars.asset_group, delcnt) elif form.errors: response.flash = 'Error in form' return dict( form=form, err404=get_oreally_404(request.folder), )
def read(): record = db.t_services(request.args(0)) or redirect( URL('default', 'error', vars={'msg': T('Service record not found')})) response.title = "%s :: Service Details :: %s/%s" % ( settings.title, record.f_proto, record.f_number) #service=crud.read(db.t_services,record) service = crud.update(db.t_services, record, next='read/[id]', ondelete=lambda form: redirect(URL('list'))) # pagination svclist = [] for svc_rec in db(db.t_services.f_hosts_id == record.f_hosts_id).select(): if svc_rec.id == record.id: svclist.append( OPTION("%s/%s" % (svc_rec.f_proto, svc_rec.f_number), _value=svc_rec.id, _selected=True)) else: svclist.append( OPTION("%s/%s" % (svc_rec.f_proto, svc_rec.f_number), _value=svc_rec.id)) #pagination = pagination_services(db, request, session, record) pagination = None # pagination_services is too slow and may not be necessary here vulntr = [] accttr = [] svcinfotr = [] # vulnerabilities q = db(db.t_service_vulns.f_services_id == record.id).select() for k in q: vulninfo = db.t_vulndata(k.f_vulndata_id) if vulninfo: if settings.use_cvss: severity = vulninfo.f_cvss_score else: severity = vulninfo.f_severity vulntr.append( TR( TD("%s/%s" % (record.f_proto, record.f_number)), TD( A(vulninfo.f_vulnid, _href=URL('vulns', 'vulninfo_by_vulnid', args=vulninfo.f_vulnid), _target="vulndata_%s" % (k.f_vulndata_id), extension='html').xml()), TD(severity), TD(k.f_status), TD(XML(k.f_proof, sanitize=False).xml()), )) # accounts q = db(db.t_accounts.f_services_id == record.id).select() for k in q: accttr.append( TR( TD("%s/%s" % (record.f_proto, record.f_number)), TD(k["f_username"]), TD(k["f_password"]), TD(k["f_source"]), TD(k["f_level"]), TD(k["f_description"]), TD(k["f_services_id"]), )) # service info q = db(db.t_service_info.f_services_id == record.id).select() for k in q: svcinfotr.append( TR( TD("%s/%s" % (record.f_proto, record.f_number)), TD(k["f_name"]), TD(k["f_text"]), )) if len(svcinfotr) > 0: svcinfotable = TABLE(THEAD( TR(TH(T('Port')), TH(T('Name')), TH(T('Text')))), TBODY(svcinfotr), _style="width:100%", _class="table table-condensed table-striped") else: svcinfotable = None if len(vulntr) > 0: vulns = TABLE(THEAD( TR(TH(T('Port')), TH(T('Vulnerability')), TH(T('Severity')), TH(T('Status')), TH(T('Proof')))), TBODY(vulntr), _style="width:100%", _class="table table-condensed") else: vulns = None if len(accttr) > 0: accts = TABLE(THEAD( TR(TH(T('Port')), TH(T('Username')), TH(T('Password')), TH(T('Source')), TH(T('Level')), TH(T('Description')), TH(T('Service')))), TBODY(accttr), _style="width:100%", _class="table table-condensed") else: accts = None # grab the notes #notes=db(db.t_host_notes.f_hosts_id == record.id)(db.t_host_notes).select(db.t_host_notes.id, db.t_host_notes.f_note) #notes = SQLTABLE( db(db.t_service_notes.f_services_id == record.id)(db.t_service_notes).select(db.t_service_notes.id, db.t_service_notes.f_note), # headers = 'labels', # _style="width:100%", # _class = "datatable", # ) response.title = "%s :: Service info :: %s ::: %s/%s" % ( settings.title, host_title_maker( db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number) return dict( service=service, record=record, svcinfotable=svcinfotable, vulns=vulns, #notes=notes, accts=accts, pagination=pagination)
def by_host(): """ Returns a list of services + serviceinfo based upon an host identifier (id, ipaddr) """ 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 :: Accounts for %s" % (settings.title, host_title_maker(record)) query = (db.t_services.f_hosts_id == record.id) if request.extension == "json": aaData = [] rows = db(query).select(db.t_accounts.ALL, db.t_services.ALL, left=db.t_services.on(db.t_accounts.f_services_id==db.t_services.id)) for r in rows: if r.t_accounts.f_compromised == True: comprdiv = '<div class="acct_compromised" name="row_id" id="%s"><span class="icon-check"></span></div>' % r.t_accounts.id else: comprdiv = '<div class="acct_uncompromised" name="row_id" id="%s"/>' % r.t_accounts.id aaData.append({ '0': A("edit", _target="accounts_update_%s" % (r.t_accounts.id), _href=URL('accounts', 'edit', args=[r.t_accounts.id], extension='html')).xml(), '1': comprdiv, '2': A("%s/%s" % (r.t_services.f_proto, r.t_services.f_number), _target="services_edit_%s" % (r.t_services.id), _href=URL('services', 'edit', args=[r.t_services.id], extension='html')).xml(), '3': A(r.t_accounts.f_username, _target="accounts_username_%s" % (r.t_accounts.f_username), _href=URL('accounts', 'by_username', vars={'username': r.t_accounts.f_username}, extension='html')).xml(), '4': r.t_accounts.f_fullname, '5': r.t_accounts.f_password, '6': r.t_accounts.f_hash1_type, '7': r.t_accounts.f_hash1, '8': r.t_accounts.f_hash2_type, '9': r.t_accounts.f_hash2, '10': r.t_accounts.f_uid, '11': r.t_accounts.f_gid, '12': r.t_accounts.f_lockout, '13': r.t_accounts.f_duration, '14': r.t_accounts.f_source, '15': r.t_accounts.f_level, '16': r.t_accounts.f_description, 'DT_RowId': r.t_accounts.id, } ) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result form = TABLE(THEAD(TR(TH(T(''), _width="5%"), TH(T('Compr'), _width="5%"), TH(T('Port')), TH(T('Username')), TH(T('Fullname')), 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('Lockout')), TH(T('Duration')), TH(T('Source')), TH(T('Level')), 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 == record.id).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, host=record, add=add)
def vulndata_by_host(): """ Returns a list of vulnerabilties based upon an host identifier (id, ipv4, ipv6) """ from skaldship.metasploit import msf_get_config msf_settings = msf_get_config(session) 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 :: Vulnerabilities for %s" % ( settings.title, host_title_maker(record)) services = db(db.t_services.f_hosts_id == record.id).select( db.t_services.id, db.t_services.f_proto, db.t_services.f_number) if request.extension == "json": aaData = [] for svc in services: # service info q = db(db.t_service_vulns.f_services_id == svc.id).select() for vulninfo in q: atxt = {} exploit_list = [] vulndetails = db( db.t_vulndata.id == vulninfo.f_vulndata_id).select( cache=(cache.ram, 300)).first() exploits = db(db.t_exploit_references.f_vulndata_id == vulninfo.f_vulndata_id).select( orderby=~db.t_exploit_references.id) if len(exploits) > 0: expl_count = "Yes (%d)" % (len(exploits)) for expl in exploits: for expl_data in db( db.t_exploits.id == expl.f_exploit_id).select( cache=(cache.ram, 300)): exp_link = expl_data.f_name if expl_data.f_source == 'exploitdb': if db.t_exploitdb[expl_data.f_title]: exploitdb_href = URL( 'exploitdb', 'detail.html', args=expl_data.f_title) else: exploitdb_href = URL( 'default', 'redirect', extension='html', vars={ 'url': 'http://www.exploit-db.com/exploits/%s' % expl_data.f_title }) exp_link = A( IMG(_align="absmiddle", _width=16, _height=16, _src=URL('static', 'images/exploitdb.ico')), ' exploitdb - ' + expl_data.f_name, _href=exploitdb_href, _target="exploitdb_%s" % (expl_data.f_name)) elif expl_data.f_source == 'metasploit': if session.msf_workspace: msf_uri = os.path.join( msf_settings['url'], 'workspaces', session.msf_workspace_num, 'modules', expl_data.f_title) else: msf_uri = URL( 'default', 'redirect', extension='html', vars={ 'url': 'http://www.rapid7.com/db/modules/%s' % expl_data.f_title }) exp_link = A( IMG(_align="absmiddle", _width=16, _height=16, _src=URL('static', 'images/msf.gif')), ' metasploit - ' + expl_data.f_name, _href=msf_uri, _target="msf_%s" % (expl_data.f_name)) elif expl_data.f_source == 'canvas': exp_link = SPAN( IMG(_align="absmiddle", _width=16, _height=16, _src=URL('static', 'images/canvas.png')), ' canvas - ' + expl_data.f_name) exploit_list.append( "%s : %s (%s/%s)" % (expl_data.f_title, exp_link, expl_data.f_rank, expl_data.f_level)) else: expl_count = "" atxt['0'] = IMG(_src=URL(request.application, 'static', 'images/details_open.png')).xml() atxt['1'] = A('edit', _target="service_vuln_update_%s" % (vulninfo.id), _href=URL('vulns', 'service_vulns_edit', args=vulninfo.id, extension='html')).xml() if vulninfo.f_exploited: atxt['2'] = '<input id="exploited" value="' + str( vulninfo.id) + '" type="checkbox", checked>' else: atxt['2'] = '<input id="exploited" value="' + str( vulninfo.id) + '" type="checkbox">' atxt['3'] = "%s/%s" % (svc.f_proto, svc.f_number) atxt['4'] = A(vulndetails.f_vulnid, _target="vulndata_%s" % (vulndetails.id), _href=URL('vulns', 'vulninfo_by_vulnid', args=vulndetails.f_vulnid, extension='html')).xml() atxt['5'] = vulndetails.f_severity atxt['6'] = vulndetails.f_cvss_score atxt['7'] = SPAN(vulninfo.f_status, _id="vulninfo_status", _vulnstatus=vulninfo.f_status).xml() atxt['8'] = expl_count atxt['9'] = MARKMIN(vulninfo.f_proof).xml() atxt['10'] = MARKMIN(vulndetails.f_description).xml() atxt['11'] = vulndetails.f_title atxt['12'] = "<br />\n".join(exploit_list) atxt['DT_RowId'] = vulninfo.id aaData.append(atxt) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result add = AddModal( db.t_service_vulns, 'Add', 'Add', 'Add Vulnerability', #fields=[ #], cmd='vulntable.fnReloadAjax();') #db.t_service_vulns.f_services_id.default = svc.id svc_set = [] for svc in services: svc_set.append([ svc.id, "%s :: %s/%s" % (host_title_maker( db.t_hosts[record.id]), svc.f_proto, svc.f_number) ]) db.t_service_vulns.f_services_id.requires = IS_IN_SET(svc_set) db.t_service_vulns.id.comment = add.create() form = TABLE(THEAD( TR( TH('', _width="5%"), TH(T(''), _width="5%"), TH(T('Pwned'), width="5%"), TH(T('Port')), TH(T('Vuln ID')), TH(T('Sev')), TH(T('CVSS')), TH(T('Status')), TH(T('Exploits')), TH(T('Proof')), TH(T('Description')), TH(T('Title')), TH(T('Exploit List')), )), _class="datatable", _id="vulntable", _style="width:100%") return dict(form=form, host=record, add=add)
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(): """ 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)
type='integer', default=0, label=T('Service Count')), Field('f_vuln_count', type='integer', default=0, label=T('Vuln Count')), Field('f_vuln_graph', type='string', default='0,0,0,0,0,0,0,0,0,0', label=T('Vuln Graph')), Field('f_exploit_count', type='integer', default=0, label=T('Exploit Count')), format=lambda r: host_title_maker(r), fake_migrate=settings.fake_migrate, migrate=settings.migrate) ######################################## ## Customer operating system records ## These SHOULD be copied from CPE but ## if not they'll be flagged as such. db.define_table('t_os', Field('id', 'id', represent=lambda id, row: SPAN( A(id, _href=URL('os', 'os_edit', args=id)))), Field('f_cpename', length=255, type='string',
def refs_by_host(): """ Returns a list of OS records based upon an host identifier (id, ipv4, ipv6) """ if request.args(0) is None: redirect(URL('default', 'error', vars={'msg': T('No host record sent')})) 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 :: OS Records for %s" % (settings.title, host_title_maker(record)) oslist = db(db.t_host_os_refs.f_hosts_id==record.id).select() aaData = [] if request.extension == "json": for osdetail in oslist: osinfo = db.t_os(osdetail['f_os_id']) # datatables json requires aaData to be specificly formatted atxt = {} atxt['0'] = A('edit', _target="oswindow_%s" % (osdetail.id), _href=URL('refs_edit', args=[osdetail.id], extension='html')).xml() atxt['1'] = osdetail.f_family atxt['2'] = osdetail.f_class atxt['3'] = osdetail.f_certainty atxt['4'] = osinfo.f_cpename atxt['5'] = osinfo.f_title atxt['DT_RowId'] = osdetail.id aaData.append(atxt) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result form = TABLE(THEAD(TR(TH(T(''), _width="5%"), TH(T('Family')), TH(T('Class')), TH(T('Certainty')), TH(T('CPE Name')), TH(T('Title')), ) ), _class="datatable", _id="ostable", _style="width:100%") add_os_refs = AddModal( db.t_host_os_refs, 'Add', 'Add', 'Add OS', fields=['f_certainty', 'f_class', 'f_family', 'f_os_id'], cmd='ostable.fnReloadAjax();' ) db.t_host_os_refs.f_hosts_id.default = record.id db.t_host_os_refs.id.comment = add_os_refs.create() add_non_cpe = AddModal( db.t_os, 'Add Non-CPE OS', 'Add Non-CPE OS', 'Add Non-CPE OS', #fields=[], #cmd='ostable.fnReloadAjax();' ) db.t_os.id.comment = add_non_cpe.create() return dict(form=form, host=record, add_os_refs=add_os_refs, add_non_cpe=add_non_cpe)
def read(): record = db.t_snmp(request.args(0)) or redirect(URL('default', 'error', vars={'msg': T('SNMP record not found')})) response.title = "%s :: SNMP :: %s" % (settings.title, host_title_maker(db.t_hosts[record.f_hosts_id])) form=crud.read(db.t_snmp,record) return dict(form=form)
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(): 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 by_host(): """ Returns a list of services + serviceinfo based upon an host identifier (id, ipv4, ipv6) """ 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 :: Services for %s" % (settings.title, host_title_maker(record)) services = db(db.t_services.f_hosts_id==record.id).select(db.t_services.id, db.t_services.f_proto, db.t_services.f_number, db.t_services.f_status, db.t_services.f_name, db.t_services.f_banner)#, cache=(cache.ram,60)) svcq = (db.t_services.f_hosts_id==record.id) infoq = (db.t_service_info.f_services_id == db.t_services.id) if request.extension == "json": #rows = db(svcq).select(db.t_services.ALL, db.t_service_info.ALL, left=db.t_service_info.on(infoq)) aaData = [] for svc in services: # service info atxt = {} q = db(db.t_service_info.f_services_id == svc.id).select() if len(q) > 0: addl = [] for svcinfo in q: addl.append(TR(TD(svcinfo.f_name), TD(svcinfo.f_text))) atxt['0'] = IMG(_src=URL(request.application,'static','images/details_open.png')).xml() atxt['1'] = TABLE(THEAD(TR(TH(T('Name')), TH(T('Text')))), TBODY(addl)).xml() else: atxt['0'] = ("") atxt['1'] = ("") atxt['2'] = A('edit', _target="services_edit_%s" % (svc.id), _href=URL('edit', args=[svc['id']], extension='html')).xml() atxt['3'] = svc.f_proto if svc.f_number in HTTP_PORTS and svc.f_proto == "tcp" or svc.f_name == "HTTP": atxt['4'] = A(svc.f_number, _href="http://%s:%s/" % (record.f_ipaddr, svc.f_number), _target="%s-tcp-%s" % (record.f_ipaddr, svc.f_number)).xml() elif svc.f_number in HTTPS_PORTS and svc.f_proto == "tcp" or svc.f_name == "HTTPS": atxt['4'] = A(svc.f_number, _href="https://%s:%s/" % (record.f_ipaddr, svc.f_number), _target="%s-tcp-%s" % (record.f_ipaddr, svc.f_number)).xml() else: atxt['4'] = svc.f_number atxt['5'] = svc.f_status atxt['6'] = svc.f_name or "" atxt['7'] = svc.f_banner or "" atxt['DT_RowId'] = svc.id aaData.append(atxt) result = { 'sEcho': request.vars._, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result 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.f_hosts_id.default = record.id db.t_services.id.comment = add.create() form = TABLE(THEAD(TR(TH('', _width="5%"), TH('Info'), TH(T('')), TH(T('Protocol')), TH(T('Number')), TH(T('Status')), TH(T('Name')), TH(T('Banner')), ) ), _class="datatable", _id="servicetable", _style="width:100%") return dict(form=form, host=record, add=add)
def by_username(): if request.vars.get('username', 'None') != 'None': record = None response.title = "%s :: Account entries for %s" % (settings.title, request.vars.username) query = (db.t_accounts.f_username.like(request.vars.username)) else: query = (db.t_accounts.active) aaData = [] rows = db(query).select(db.t_accounts.ALL, db.t_hosts.ALL, db.t_services.ALL, left=(db.t_services.on(db.t_accounts.f_services_id==db.t_services.id), db.t_hosts.on(db.t_hosts.id == db.t_services.f_hosts_id))) for r in rows: atxt=[] hostrec=db.t_hosts[r.t_hosts.id] atxt.append(TD(A("edit", _target="accounts_update_%s" % (r.t_accounts.id), _href=URL('accounts', 'edit', args=[r.t_accounts.id], extension='html')))) atxt.append(TD(INPUT(_name="id", _value=str(r.t_accounts.id), _type="checkbox"))) atxt.append(TD(A("%s" % (host_title_maker(hostrec)), _target="host_detail_%s" % (r.t_hosts.id), _href=URL('hosts', 'detail', args=[r.t_hosts.id])))) atxt.append(TD(A("%s/%s" % (r.t_services.f_proto, r.t_services.f_number), _target="services_edit_%s" % (r.t_services.id), _href=URL('services', 'edit',args=[r.t_services.id], extension='html')))) atxt.append(TD(r.t_accounts.f_username)) atxt.append(TD(r.t_accounts.f_fullname)) atxt.append(TD(r.t_accounts.f_password)) atxt.append(TD(r.t_accounts.f_compromised)) atxt.append(TD(r.t_accounts.f_hash1_type)) atxt.append(TD(r.t_accounts.f_hash1)) atxt.append(TD(r.t_accounts.f_hash2_type)) atxt.append(TD(r.t_accounts.f_hash2)) atxt.append(TD(r.t_accounts.f_uid)) atxt.append(TD(r.t_accounts.f_gid)) atxt.append(TD(r.t_accounts.f_lockout)) atxt.append(TD(r.t_accounts.f_duration)) atxt.append(TD(r.t_accounts.f_source)) atxt.append(TD(r.t_accounts.f_level)) atxt.append(TD(r.t_accounts.f_description)) aaData.append(TR(atxt)) form = TABLE(THEAD(TR(TH(T('ID'), _width="5%"), TH(T(''), _width="2%"), TH(T('Host')), TH(T('Port')), TH(T('Username')), TH(T('Fullname')), TH(T('Password')), TH(T('Compromised')), 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('Lockout')), TH(T('Duration')), TH(T('Source')), TH(T('Level')), TH(T('Description')), ) ), TBODY(aaData), _class="datatable", _id="accounttable", _style="width:100%") return dict(form=form)
def purge_data(): # Purges all the data except user tables response.title = "%s :: Database Purge" % (settings.title) users = db(db.auth_user).select() userlist = [] for user in users: userlist.append([user.id, user.username]) hosts = db(db.t_hosts).select() hostlist = [] for host in hosts: hostlist.append([host.id, host_title_maker(host)]) ag_rows = db(db.t_hosts).select(db.t_hosts.f_asset_group, distinct=True).as_list() asset_groups = [] for ag in ag_rows: asset_groups.append(ag['f_asset_group']) form = SQLFORM.factory( Field('host', type='list:integer', label=T('Delete a host'), requires=IS_EMPTY_OR(IS_IN_SET(hostlist))), Field('engineer', type='list:integer', label=T('Hosts by user'), requires=IS_EMPTY_OR(IS_IN_SET(userlist))), Field('asset_group', type='string', label=T('Asset Group'), requires=IS_EMPTY_OR(IS_IN_SET(asset_groups))), Field('all_data', type='boolean', label=T('Truncate all tables')), Field('are_you_sure', type='boolean', label=T('Are you sure?'), requires=IS_NOT_EMPTY(error_message='ARE YOU SURE?!?!')), ) if form.accepts(request.vars, session): if not form.vars.are_you_sure: form.errors.are_you_sure = 'ARE YOU SURE?' else: if form.vars.all_data: db.t_hosts.truncate(mode="CASCADE") db.t_services.truncate(mode="CASCADE") db.t_os.truncate(mode="CASCADE") db.t_host_os_refs.truncate(mode="CASCADE") db.t_apps.truncate(mode="CASCADE") db.t_services_apps_refs.truncate(mode="CASCADE") db.t_service_vulns.truncate(mode="CASCADE") db.t_service_info.truncate(mode="CASCADE") db.t_accounts.truncate(mode="CASCADE") db.t_host_notes.truncate(mode="CASCADE") db.t_evidence.truncate(mode="CASCADE") db.t_snmp.truncate(mode="CASCADE") db.commit() response.flash = 'All data purged' elif form.vars.host: host_id = form.vars.host del db.t_hosts[host_id] response.flash = "Host %s purged" % (form.vars.host) elif form.vars.engineer: # TODO: Test this delcnt = db( db.t_hosts.f_engineer == form.vars.engineer).delete() db.commit() response.flash = "Hosts owned by %s purged (%d records)" % ( form.vars.engineer, delcnt) elif form.vars.asset_group: delcnt = db(db.t_hosts.f_asset_group == form.vars.asset_group).delete() db.commit() response.flash = "Asset group %s purged (%d records)" % ( form.vars.asset_group, delcnt) elif form.errors: response.flash = 'Error in form' return dict( form=form, err404=get_oreally_404(request.folder), )
def import_file(): """ Import and parse password file into t_accounts """ import os from skaldship.general import check_datadir check_datadir(request.folder) # Service_id is primary, host_id is secondary, if none then list # all the services svc_set = [] url=URL('accounts', 'import_file') if request.vars.has_key('service_id'): try: record = db.t_services[request.vars.service_id] svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) url = URL('accounts', 'import_file', vars={'service_id':request.vars.service_id}) except: pass elif request.vars.has_key('host_id'): try: host_record = get_host_record(request.vars.host_id) svc_records = db(db.t_services.f_hosts_id == host_record.id).select(cache=(cache.ram, 30)) url = URL('accounts', 'import_file', vars={'host_id':request.vars.host_id}) for record in svc_records: svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) except: pass if len(svc_set) == 0: # all services svc_records = db(db.t_services).select(cache=(cache.ram,30)) svc_set = [] for record in svc_records: svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number))) if request.extension == "load": buttons=[] else: buttons=['submit'] form = SQLFORM.factory( Field('f_service', 'string', label=T('Host / Service'), requires=IS_IN_SET(svc_set), default=svc_set[0][0]), Field('f_filename', 'upload', uploadfolder=os.path.join(request.folder, settings.password_upload_dir), label=T('Password file')), Field('f_type', 'string', label=T('File type'), default='PWDUMP', requires=IS_IN_SET(settings.password_file_types)), Field('f_source', 'string', label=T('Source (if necessary)')), Field('f_add_to_evidence', 'boolean', label=T('Add Evidence')), Field('f_taskit', type='boolean', default=True, label=T('Run in background task')), buttons=buttons, _action=url, _id='accounts_import_form' ) resp_text = "" accounts_added = [] accounts_updated = [] if form.errors: response.flash = 'Error in form' return TABLE(*[TR(k, v) for k, v in form.errors.items()]) elif form.accepts(request.vars, session): if form.vars.f_filename is not None: orig_filename = request.vars.f_filename.filename filename = os.path.join(request.folder, settings.password_upload_dir, form.vars.f_filename) if form.vars.f_taskit: task = scheduler.queue_task( accounts_import_file, pvars=dict( filename=filename, service=form.vars.f_service, f_type=form.vars.f_type, f_source=form.vars.f_source ), group_name=settings.scheduler_group_name, sync_output=5, timeout=settings.scheduler_timeout ) if task.id: resp_text = "Submitted file for processing: %s" % (A("task " + str(task.id), _href=URL(c='tasks', f='status', args=task.id)).xml()) else: resp_text = "Error submitting job: %s" % (task.errors) else: logger.info("Processing password file: %s" % (filename)) account_data = process_password_file( pw_file=filename, file_type=request.vars.f_type, source=request.vars.f_source ) resp_text = insert_or_update_acct(form.vars.f_service, account_data) logger.info(resp_text) if form.vars.f_add_to_evidence is True: # add the password file to evidence try: pwdata = open(filename, "r").readlines() except Exception, e: logger.error("Error opening %s: %s" % (filename, e)) db.t_evidence.insert( f_hosts_id = db.t_services[form.vars.f_service].f_hosts_id, f_type = 'Password File', f_text = form.vars.f_type, f_filename = orig_filename, f_evidence = form.vars.f_filename, f_data = pwdata) db.commit()
def vulndata_by_host(): """ Returns a list of vulnerabilties based upon an host identifier (id, ipv4, ipv6) """ from skaldship.metasploit import msf_get_config msf_settings = msf_get_config(session) 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 :: Vulnerabilities for %s" % (settings.title, host_title_maker(record)) services = db(db.t_services.f_hosts_id==record.id).select(db.t_services.id, db.t_services.f_proto, db.t_services.f_number) if request.extension == "json": aaData = [] for svc in services: # service info q = db(db.t_service_vulns.f_services_id == svc.id).select() for vulninfo in q: atxt = {} exploit_list = [] vulndetails = db(db.t_vulndata.id == vulninfo.f_vulndata_id).select(cache=(cache.ram, 300)).first() exploits = db(db.t_exploit_references.f_vulndata_id == vulninfo.f_vulndata_id).select(orderby=~db.t_exploit_references.id) if len(exploits) > 0: expl_count = "Yes (%d)" % (len(exploits)) for expl in exploits: for expl_data in db(db.t_exploits.id == expl.f_exploit_id).select(cache=(cache.ram, 300)): exp_link = expl_data.f_name if expl_data.f_source == 'exploitdb': if db.t_exploitdb[expl_data.f_title]: exploitdb_href = URL('exploitdb', 'detail.html', args=expl_data.f_title) else: exploitdb_href = URL('default', 'redirect', extension='html', vars={'url': 'http://www.exploit-db.com/exploits/%s' % expl_data.f_title}) exp_link = A(IMG(_align="absmiddle", _width=16, _height=16, _src=URL('static','images/exploitdb.ico')), ' exploitdb - ' + expl_data.f_name,_href=exploitdb_href, _target="exploitdb_%s" % (expl_data.f_name)) elif expl_data.f_source == 'metasploit': if session.msf_workspace: msf_uri = os.path.join(msf_settings['url'], 'workspaces', session.msf_workspace_num, 'modules', expl_data.f_title) else: msf_uri = URL('default', 'redirect', extension='html', vars={'url': 'http://www.rapid7.com/db/modules/%s' % expl_data.f_title}) exp_link = A(IMG(_align="absmiddle", _width=16, _height=16, _src=URL('static','images/msf.gif')), ' metasploit - ' + expl_data.f_name, _href=msf_uri, _target="msf_%s" % (expl_data.f_name)) elif expl_data.f_source == 'canvas': exp_link = SPAN(IMG(_align="absmiddle", _width=16, _height=16, _src=URL('static','images/canvas.png')), ' canvas - ' + expl_data.f_name) exploit_list.append("%s : %s (%s/%s)" % (expl_data.f_title, exp_link, expl_data.f_rank, expl_data.f_level)) else: expl_count = "" atxt['0'] = IMG(_src=URL(request.application,'static','images/details_open.png')).xml() atxt['1'] = A('edit', _target="service_vuln_update_%s" % (vulninfo.id), _href=URL('vulns', 'service_vulns_edit', args=vulninfo.id, extension='html')).xml() if vulninfo.f_exploited: atxt['2'] = '<input id="exploited" value="' + str(vulninfo.id) + '" type="checkbox", checked>' else: atxt['2'] = '<input id="exploited" value="' + str(vulninfo.id) + '" type="checkbox">' atxt['3'] = "%s/%s" % (svc.f_proto, svc.f_number) atxt['4'] = A(vulndetails.f_vulnid, _target="vulndata_%s" % (vulndetails.id), _href=URL('vulns', 'vulninfo_by_vulnid', args=vulndetails.f_vulnid, extension='html')).xml() atxt['5'] = vulndetails.f_severity atxt['6'] = vulndetails.f_cvss_score atxt['7'] = SPAN(vulninfo.f_status,_id="vulninfo_status",_vulnstatus=vulninfo.f_status).xml() atxt['8'] = expl_count atxt['9'] = MARKMIN(vulninfo.f_proof).xml() atxt['10'] = MARKMIN(vulndetails.f_description).xml() atxt['11'] = vulndetails.f_title atxt['12'] = "<br />\n".join(exploit_list) atxt['DT_RowId'] = vulninfo.id aaData.append(atxt) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result add = AddModal( db.t_service_vulns, 'Add', 'Add', 'Add Vulnerability', #fields=[ #], cmd='vulntable.fnReloadAjax();' ) #db.t_service_vulns.f_services_id.default = svc.id svc_set = [] for svc in services: svc_set.append([svc.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.id]), svc.f_proto, svc.f_number)]) db.t_service_vulns.f_services_id.requires = IS_IN_SET(svc_set) db.t_service_vulns.id.comment = add.create() form = TABLE(THEAD(TR(TH('', _width="5%"), TH(T(''), _width="5%"), TH(T('Pwned'), width="5%"), TH(T('Port')), TH(T('Vuln ID')), TH(T('Sev')), TH(T('CVSS')), TH(T('Status')), TH(T('Exploits')), TH(T('Proof')), TH(T('Description')), TH(T('Title')), TH(T('Exploit List')), ) ), _class="datatable", _id="vulntable", _style="width:100%") return dict(form=form, host=record, 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 by_username(): if request.vars.get("username", "None") != "None": record = None response.title = "%s :: Account entries for %s" % (settings.title, request.vars.username) query = db.t_accounts.f_username.like(request.vars.username) else: query = db.t_accounts.active aaData = [] rows = db(query).select( db.t_accounts.ALL, db.t_hosts.ALL, db.t_services.ALL, left=( db.t_services.on(db.t_accounts.f_services_id == db.t_services.id), db.t_hosts.on(db.t_hosts.id == db.t_services.f_hosts_id), ), ) for r in rows: atxt = [] hostrec = db.t_hosts[r.t_hosts.id] atxt.append( TD( A( "edit", _target="accounts_update_%s" % (r.t_accounts.id), _href=URL("accounts", "edit", args=[r.t_accounts.id], extension="html"), ) ) ) atxt.append(TD(INPUT(_name="id", _value=str(r.t_accounts.id), _type="checkbox"))) atxt.append( TD( A( "%s" % (host_title_maker(hostrec)), _target="host_detail_%s" % (r.t_hosts.id), _href=URL("hosts", "detail", args=[r.t_hosts.id]), ) ) ) atxt.append( TD( A( "%s/%s" % (r.t_services.f_proto, r.t_services.f_number), _target="services_edit_%s" % (r.t_services.id), _href=URL("services", "edit", args=[r.t_services.id], extension="html"), ) ) ) atxt.append(TD(r.t_accounts.f_username)) atxt.append(TD(r.t_accounts.f_fullname)) atxt.append(TD(r.t_accounts.f_password)) atxt.append(TD(r.t_accounts.f_compromised)) atxt.append(TD(r.t_accounts.f_hash1_type)) atxt.append(TD(r.t_accounts.f_hash1)) atxt.append(TD(r.t_accounts.f_hash2_type)) atxt.append(TD(r.t_accounts.f_hash2)) atxt.append(TD(r.t_accounts.f_uid)) atxt.append(TD(r.t_accounts.f_gid)) atxt.append(TD(r.t_accounts.f_lockout)) atxt.append(TD(r.t_accounts.f_duration)) atxt.append(TD(r.t_accounts.f_source)) atxt.append(TD(r.t_accounts.f_level)) atxt.append(TD(r.t_accounts.f_description)) aaData.append(TR(atxt)) form = TABLE( THEAD( TR( TH(T("ID"), _width="5%"), TH(T(""), _width="2%"), TH(T("Host")), TH(T("Port")), TH(T("Username")), TH(T("Fullname")), TH(T("Password")), TH(T("Compromised")), 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("Lockout")), TH(T("Duration")), TH(T("Source")), TH(T("Level")), TH(T("Description")), ) ), TBODY(aaData), _class="datatable", _id="accounttable", _style="width:100%", ) return dict(form=form)
def read(): record = db.t_services(request.args(0)) or redirect(URL('default', 'error', vars={'msg': T('Service record not found')})) response.title = "%s :: Service Details :: %s/%s" % (settings.title, record.f_proto, record.f_number) #service=crud.read(db.t_services,record) service=crud.update(db.t_services,record,next='read/[id]', ondelete=lambda form: redirect(URL('list'))) # pagination svclist = [] for svc_rec in db(db.t_services.f_hosts_id==record.f_hosts_id).select(): if svc_rec.id == record.id: svclist.append(OPTION("%s/%s" % (svc_rec.f_proto, svc_rec.f_number), _value=svc_rec.id, _selected=True)) else: svclist.append(OPTION("%s/%s" % (svc_rec.f_proto, svc_rec.f_number), _value=svc_rec.id)) #pagination = pagination_services(db, request, session, record) pagination = None # pagination_services is too slow and may not be necessary here vulntr = [] accttr = [] svcinfotr = [] # vulnerabilities q = db(db.t_service_vulns.f_services_id == record.id).select() for k in q: vulninfo = db.t_vulndata(k.f_vulndata_id) if vulninfo: if settings.use_cvss: severity = vulninfo.f_cvss_score else: severity = vulninfo.f_severity vulntr.append(TR(TD("%s/%s" % (record.f_proto, record.f_number)), TD(A(vulninfo.f_vulnid, _href=URL('vulns', 'vulninfo_by_vulnid', args=vulninfo.f_vulnid), _target="vulndata_%s" % (k.f_vulndata_id), extension='html').xml()), TD(severity), TD(k.f_status), TD(XML(k.f_proof, sanitize=False).xml()), ) ) # accounts q = db(db.t_accounts.f_services_id == record.id).select() for k in q: accttr.append(TR(TD("%s/%s" % (record.f_proto, record.f_number)), TD(k["f_username"]), TD(k["f_password"]), TD(k["f_source"]), TD(k["f_level"]), TD(k["f_description"]), TD(k["f_services_id"]), ) ) # service info q = db(db.t_service_info.f_services_id == record.id).select() for k in q: svcinfotr.append(TR(TD("%s/%s" % (record.f_proto, record.f_number)), TD(k["f_name"]), TD(k["f_text"]), ) ) if len(svcinfotr) > 0: svcinfotable = TABLE(THEAD(TR(TH(T('Port')), TH(T('Name')), TH(T('Text')))), TBODY(svcinfotr), _style="width:100%", _class="table table-condensed table-striped") else: svcinfotable = None if len(vulntr) > 0: vulns = TABLE(THEAD(TR(TH(T('Port')), TH(T('Vulnerability')), TH(T('Severity')), TH(T('Status')), TH(T('Proof')))), TBODY(vulntr), _style="width:100%", _class="table table-condensed") else: vulns = None if len(accttr) > 0: accts = TABLE(THEAD(TR(TH(T('Port')), TH(T('Username')), TH(T('Password')), TH(T('Source')), TH(T('Level')), TH(T('Description')), TH(T('Service')))), TBODY(accttr), _style="width:100%", _class="table table-condensed") else: accts = None # grab the notes #notes=db(db.t_host_notes.f_hosts_id == record.id)(db.t_host_notes).select(db.t_host_notes.id, db.t_host_notes.f_note) #notes = SQLTABLE( db(db.t_service_notes.f_services_id == record.id)(db.t_service_notes).select(db.t_service_notes.id, db.t_service_notes.f_note), # headers = 'labels', # _style="width:100%", # _class = "datatable", # ) response.title = "%s :: Service info :: %s ::: %s/%s" % (settings.title, host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number) return dict(service=service, record=record, svcinfotable=svcinfotable, vulns=vulns, #notes=notes, accts=accts, pagination=pagination)
def by_host(): """ Returns a list of OS records based upon an host identifier (id, ipv4, ipv6) """ if request.args(0) is None: redirect( URL('default', 'error', vars={'msg': T('Host record not found')})) 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 :: SNMP Records for %s" % (settings.title, host_title_maker(record)) snmplist = db(db.t_snmp.f_hosts_id == record.id).select() aaData = [] if request.extension == "json": for snmp in snmplist: # datatables json requires aaData to be specificly formatted aaData.append({ '0': A("edit", _target="snmp_update_%s" % (snmp.id), _href=URL('edit', extension='html', args=snmp.id)).xml(), '1': snmp.f_community, '2': snmp.f_version, '3': snmp.f_access, 'DT_RowId': snmp.id, }) result = { 'sEcho': request.vars.sEcho, 'iTotalRecords': len(aaData), 'aaData': aaData, } return result form = TABLE(THEAD( TR( TH(T('ID'), _width="5%"), TH(T('Community')), TH(T('Version')), TH(T('Access')), )), _class="datatable", _id="snmptable", _style="width:100%") add = AddModal(db.t_snmp, 'Add', 'Add', 'Add SNMP String', fields=['f_community', 'f_version', 'f_access'], cmd='snmptable.fnReloadAjax();') db.t_snmp.f_hosts_id.default = record.id db.t_snmp.id.comment = add.create() return dict(form=form, host=record, add=add)