예제 #1
0
파일: vulns.py 프로젝트: v0re/Kvasir
def service_vulns_list():
    # XXX: this doesn't work yet. . .

    query = (db.t_service_vulns.id >
             0) & (db.t_service_vulns.f_services_id == db.t_services.id) & (
                 db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)
    query = create_hostfilter_query(session.hostfilter, query, 't_services')

    columns = [
        db.t_hosts.f_ipaddr,
        db.t_hosts.f_hostname,
        db.t_services.f_proto,
        db.t_services.f_number,
        db.t_vulndata.f_vulnid,
        db.t_service_vulns.f_status,
        db.t_service_vulns.f_proof,
        #db.t_service_vulns.id
    ]
    rows = SQLFORM.grid(query,
                        columns,
                        deletable=True,
                        selectable=True,
                        details=False,
                        field_id=db.t_service_vulns.id)
    response.title = "Services with Vulnerabilities"
    return dict(rows=rows)
예제 #2
0
파일: vulns.py 프로젝트: v0re/Kvasir
def vuln_hosts_by_vulnid():
    """
    Returns a grid of hosts based on f_vulndata_id
    """
    vuln_id = request.args(0) or None
    query = (db.t_hosts.id > 0)
    query = create_hostfilter_query(session.hostfilter, query, 't_services')
    query &= (db.t_services.f_hosts_id == db.t_hosts.id)
    query &= (db.t_service_vulns.f_services_id == db.t_services.id)
    query &= (db.t_service_vulns.f_vulndata_id == vuln_id)
    hosts = SQLFORM.grid(
        query,
        args=[vuln_id],
        fields=[
            db.t_hosts.f_ipaddr,
            db.t_hosts.f_hostname,
            db.t_services.f_proto,
            db.t_services.f_number,
            db.t_service_vulns.f_proof,
        ],
        maxtextlength=255,
        searchable=True,
        deletable=True,
        details=False,
        selectable=True,
        create=False,
        csv=True,
        formstyle='bootstrap',
        formname='vuln_hosts_grid',
        client_side_delete=True,
        paginate=None,
    )
    return hosts
예제 #3
0
def vuln_hosts_by_vulnid():
    """
    Returns a grid of hosts based on f_vulndata_id
    """
    vuln_id = request.args(0) or None
    query = (db.t_hosts.id > 0)
    query = create_hostfilter_query(session.hostfilter, query, 't_services')
    query &= (db.t_services.f_hosts_id == db.t_hosts.id)
    query &= (db.t_service_vulns.f_services_id == db.t_services.id)
    query &= (db.t_service_vulns.f_vulndata_id == vuln_id)
    hosts = SQLFORM.grid(
        query,
        args=[vuln_id],
        fields = [
            db.t_hosts.f_ipaddr,
            db.t_hosts.f_hostname,
            db.t_services.f_proto,
            db.t_services.f_number,
            db.t_service_vulns.f_proof,
        ],
        maxtextlength=255,
        searchable=True,
        deletable=True,
        details=False,
        selectable=True,
        create=False,
        csv=True,
        formstyle='bootstrap',
        formname='vuln_hosts_grid',
        client_side_delete=True,
        paginate=None,
    )
    return hosts
예제 #4
0
파일: stats.py 프로젝트: caoimhinp/Kvasir
def services():
    """
    Service statistics
    """

    t_hosts = db.t_hosts
    t_svcs = db.t_services

    q = (t_hosts.id > 0)
    q = create_hostfilter_query(session.hostfilter, q, t_svcs)

    rows = db(q).select(t_svcs.f_proto, t_svcs.f_number, t_svcs.f_name, cache=(cache.ram, 60))
    port_counts = {}
    name_counts = {}
    for r in rows:
        port = "%s/%s" % (r.f_proto, r.f_number)
        sname = r.f_name

        count = port_counts.setdefault(port, 0)
        count += 1
        port_counts[port] = count

        count = name_counts.setdefault(sname, 0)
        count += 1
        name_counts[sname] = count

    response.title = "%s :: Service Statistics" % (settings.title)

    return dict(
        port_counts=port_counts,
        name_counts=name_counts,
    )
예제 #5
0
파일: accounts.py 프로젝트: kimdane/Kvasir
def accounts_grid():
    response.title = "%s :: Accounts" % (settings.title)
    if session.hostfilter is None:
        session.hostfilter = [(None, None), False]

    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")
    columns = [
        db.t_hosts.f_ipv4,
        db.t_hosts.f_hostname,
        db.t_services.f_proto,
        db.t_services.f_number,
        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_duration,
        db.t_accounts.f_source,
        db.t_accounts.f_message,
        db.t_accounts.f_description,
        db.t_accounts.id,
    ]
    rows = SQLFORM.grid(query, columns, deletable=True, selectable=True, details=False, field_id=db.t_accounts.id)

    return dict(rows=rows)
예제 #6
0
파일: stats.py 프로젝트: Python3pkg/Kvasir
def services():
    """
    Service statistics
    """

    t_hosts = db.t_hosts
    t_svcs = db.t_services

    q = (t_hosts.id > 0)
    q = create_hostfilter_query(session.hostfilter, q, t_svcs)

    rows = db(q).select(t_svcs.f_proto,
                        t_svcs.f_number,
                        t_svcs.f_name,
                        cache=(cache.ram, 60))
    port_counts = {}
    name_counts = {}
    for r in rows:
        port = "%s/%s" % (r.f_proto, r.f_number)
        sname = r.f_name

        count = port_counts.setdefault(port, 0)
        count += 1
        port_counts[port] = count

        count = name_counts.setdefault(sname, 0)
        count += 1
        name_counts[sname] = count

    response.title = "%s :: Service Statistics" % (settings.title)

    return dict(
        port_counts=port_counts,
        name_counts=name_counts,
    )
예제 #7
0
파일: stats.py 프로젝트: v0re/Kvasir
def os():
    """
    Operating system statistics
    """

    q = create_hostfilter_query(session.hostfilter)

    rows = db(q).select(db.t_hosts.id, db.t_host_os_refs.f_certainty, db.t_os.f_title, db.t_os.f_vendor,
                        db.t_host_os_refs.f_family, db.t_host_os_refs.f_class,
                        left=(db.t_host_os_refs.on(db.t_hosts.id==db.t_host_os_refs.f_hosts_id),
                              db.t_os.on(db.t_os.id==db.t_host_os_refs.f_os_id)),
                        orderby=db.t_hosts.id|~db.t_host_os_refs.f_certainty, cache=(cache.ram, 60))

    seen = set()
    os_counts = {}
    vendor_counts = {}
    family_counts = {}
    class_counts = {}
    for r in rows:
        if r.t_hosts.id not in seen and not seen.add(r.t_hosts.id): # kludge way to select only rows per host with the best OS-guess
            os_title = r.t_os.f_title or 'Unknown'
            os_vendor = r.t_os.f_vendor or 'Unknown'
            os_family = r.t_host_os_refs.f_family or 'Unknown'
            os_class = r.t_host_os_refs.f_class or 'Unknown'

            # only capitalize if the first char of the string isn't already capitalized
            # this covers not destroying things like HP, IOS, etc
            #if os_vendor[0].islower(): os_vendor = os_vendor.capitalize()
            if os_family[0].islower(): os_family = os_family.capitalize()
            if os_class[0].islower(): os_class = os_class.capitalize()

            count = os_counts.setdefault(os_title, 0)
            count += 1
            os_counts[os_title] = count

            count = vendor_counts.setdefault(os_vendor, 0)
            count += 1
            vendor_counts[os_vendor] = count

            count = family_counts.setdefault(os_family, 0)
            count += 1
            family_counts[os_family] = count

            count = class_counts.setdefault(os_class, 0)
            count += 1
            class_counts[os_class] = count

    response.title = "%s :: Operating System Statistics" % (settings.title)

    return dict(
        vendor_counts=vendor_counts,
        os_counts=os_counts,
        family_counts=family_counts,
        class_counts=class_counts,
    )
예제 #8
0
파일: stats.py 프로젝트: caoimhinp/Kvasir
def os():
    """
    Operating system statistics
    """

    q = create_hostfilter_query(session.hostfilter)

    rows = db(q).select(db.t_hosts.id, db.t_host_os_refs.f_certainty, db.t_os.f_title, db.t_os.f_vendor,
                        db.t_host_os_refs.f_family, db.t_host_os_refs.f_class,
                        left=(db.t_host_os_refs.on(db.t_hosts.id==db.t_host_os_refs.f_hosts_id),
                              db.t_os.on(db.t_os.id==db.t_host_os_refs.f_os_id)),
                        orderby=db.t_hosts.id|~db.t_host_os_refs.f_certainty, cache=(cache.ram, 60))

    seen = set()
    os_counts = {}
    vendor_counts = {}
    family_counts = {}
    class_counts = {}
    for r in rows:
        if r.t_hosts.id not in seen and not seen.add(r.t_hosts.id): # kludge way to select only rows per host with the best OS-guess
            os_title = r.t_os.f_title or 'Unknown'
            os_vendor = r.t_os.f_vendor or 'Unknown'
            os_family = r.t_host_os_refs.f_family or 'Unknown'
            os_class = r.t_host_os_refs.f_class or 'Unknown'

            # only capitalize if the first char of the string isn't already capitalized
            # this covers not destroying things like HP, IOS, etc
            #if os_vendor[0].islower(): os_vendor = os_vendor.capitalize()
            if os_family[0].islower(): os_family = os_family.capitalize()
            if os_class[0].islower(): os_class = os_class.capitalize()

            count = os_counts.setdefault(os_title, 0)
            count += 1
            os_counts[os_title] = count

            count = vendor_counts.setdefault(os_vendor, 0)
            count += 1
            vendor_counts[os_vendor] = count

            count = family_counts.setdefault(os_family, 0)
            count += 1
            family_counts[os_family] = count

            count = class_counts.setdefault(os_class, 0)
            count += 1
            class_counts[os_class] = count

    response.title = "%s :: Operating System Statistics" % (settings.title)

    return dict(
        vendor_counts=vendor_counts,
        os_counts=os_counts,
        family_counts=family_counts,
        class_counts=class_counts,
    )
예제 #9
0
def service_vulns_list():
    # XXX: this doesn't work yet. . .

    query = (db.t_service_vulns.id > 0) & (db.t_service_vulns.f_services_id == db.t_services.id) & (db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)
    query = create_hostfilter_query(session.hostfilter, query, 't_services')

    columns = [
        db.t_hosts.f_ipaddr, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number,
        db.t_vulndata.f_vulnid, db.t_service_vulns.f_status, db.t_service_vulns.f_proof,
        #db.t_service_vulns.id
    ]
    rows = SQLFORM.grid(query, columns, deletable=True, selectable=True, details=False, field_id=db.t_service_vulns.id)
    response.title = "Services with Vulnerabilities"
    return dict(rows=rows)
예제 #10
0
def vulnlist(qstr="%", hostfilter=None):
    """
    Returns a vulnerability dictionary with counts:

    :param qstr: Vulnerability identity for .like()
    :param hostfilter: A valid hostfilter or None
    :returns dict: { 'vulnerability id': [ status, count, severity, cvss ] }
    """

    db = current.globalenv['db']
    session = current.globalenv['session']

    status = db.t_service_vulns.f_status
    svcv_id = db.t_service_vulns.id
    vulnid = db.t_vulndata.id
    f_vulnid = db.t_vulndata.f_vulnid
    f_title = db.t_vulndata.f_title
    sev = db.t_vulndata.f_severity
    cvss = db.t_vulndata.f_cvss_score

    hostfilter = hostfilter or session.hostfilter

    query = db.t_vulndata.f_vulnid.like(qstr)
    query &= (db.t_service_vulns.f_services_id == db.t_services.id) & (
        db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)
    query = create_hostfilter_query(hostfilter, query, 't_services')
    #query = (db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)

    vulnlist = {}
    for rec in db(query).select(status, vulnid, f_vulnid, f_title, svcv_id,
                                sev, cvss):
        q2 = (query &
              ((db.t_service_vulns.f_vulndata_id == rec.t_vulndata.id) &
               (db.t_service_vulns.f_status == rec.t_service_vulns.f_status)))
        vcount = db(q2).count()
        vstats = vulnlist.setdefault(rec.t_vulndata.f_vulnid, list())
        if rec.t_service_vulns.f_status not in [a[0] for a in vstats]:
            ecount = db(db.t_exploit_references.f_vulndata_id ==
                        rec.t_vulndata.id).count()
            vstats.append([
                rec.t_service_vulns.f_status,
                vcount,
                rec.t_vulndata.f_severity,
                rec.t_vulndata.f_cvss_score,
                rec.t_vulndata.f_title,
                ecount,
            ])
            vulnlist[rec.t_vulndata.f_vulnid] = vstats

    return vulnlist
예제 #11
0
파일: accounts.py 프로젝트: v0re/Kvasir
def accounts_grid():
    response.title = "%s :: Accounts" % (settings.title)

    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')
    columns = [
        db.t_hosts.f_ipaddr, db.t_hosts.f_hostname, db.t_services.f_proto, db.t_services.f_number,
        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_duration, db.t_accounts.f_source, db.t_accounts.f_message,
        db.t_accounts.f_description, db.t_accounts.id,
    ]
    rows = SQLFORM.grid(query, columns, deletable=True, selectable=True, details=False, field_id=db.t_accounts.id)

    return dict(rows=rows)
예제 #12
0
def vulnlist(query="%", hostfilter=None):
    """
    Returns a vulnerability dictionary with counts:

    { 'vulnerability id': [ status, count, severity, cvss ] }
    """

    db = current.globalenv['db']
    session = current.globalenv['session']

    status = db.t_service_vulns.f_status
    svcv_id = db.t_service_vulns.id
    vulnid = db.t_vulndata.id
    f_vulnid = db.t_vulndata.f_vulnid
    sev = db.t_vulndata.f_severity
    cvss = db.t_vulndata.f_cvss_score

    hostfilter = hostfilter or session.hostfilter

    if hostfilter is None:
        # if no filter is set then we blank it out
        if session.hostfilter is None:
            session.hostfilter = [(None, None), False]

    query = (db.t_vulndata.f_vulnid.contains(query))
    query &= (db.t_service_vulns.f_services_id == db.t_services.id) & (
        db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)
    query = create_hostfilter_query(hostfilter, query, 't_services')
    #query = (db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)

    vulnlist = {}
    for rec in db(query).select(status, vulnid, f_vulnid, svcv_id, sev, cvss):
        q2 = (query &
              ((db.t_service_vulns.f_vulndata_id == rec.t_vulndata.id) &
               (db.t_service_vulns.f_status == rec.t_service_vulns.f_status)))
        count = db(q2).count()
        vstats = vulnlist.setdefault(rec.t_vulndata.f_vulnid, list())
        if rec.t_service_vulns.f_status not in map(lambda a: a[0], vstats):
            vstats.append([
                rec.t_service_vulns.f_status, count, rec.t_vulndata.f_severity,
                rec.t_vulndata.f_cvss_score
            ])
            vulnlist[rec.t_vulndata.f_vulnid] = vstats

    return vulnlist
예제 #13
0
def vulnlist(qstr="%", hostfilter=None):
    """
    Returns a vulnerability dictionary with counts:

    :param qstr: Vulnerability identity for .like()
    :param hostfilter: A valid hostfilter or None
    :returns dict: { 'vulnerability id': [ status, count, severity, cvss ] }
    """

    db = current.globalenv['db']
    session = current.globalenv['session']

    status = db.t_service_vulns.f_status
    svcv_id = db.t_service_vulns.id
    vulnid = db.t_vulndata.id
    f_vulnid = db.t_vulndata.f_vulnid
    f_title = db.t_vulndata.f_title
    sev = db.t_vulndata.f_severity
    cvss = db.t_vulndata.f_cvss_score

    hostfilter = hostfilter or session.hostfilter

    query = db.t_vulndata.f_vulnid.like(qstr)
    query &= (db.t_service_vulns.f_services_id == db.t_services.id) & (db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)
    query = create_hostfilter_query(hostfilter, query, 't_services')
    #query = (db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)

    vulnlist = {}
    for rec in db(query).select(status, vulnid, f_vulnid, f_title, svcv_id, sev, cvss):
        q2 = (query & ((db.t_service_vulns.f_vulndata_id == rec.t_vulndata.id) &
             (db.t_service_vulns.f_status == rec.t_service_vulns.f_status)))
        vcount = db(q2).count()
        vstats = vulnlist.setdefault(rec.t_vulndata.f_vulnid, list())
        if rec.t_service_vulns.f_status not in map(lambda a:a[0], vstats):
            ecount = db(db.t_exploit_references.f_vulndata_id==rec.t_vulndata.id).count()
            vstats.append([rec.t_service_vulns.f_status,
                            vcount,
                            rec.t_vulndata.f_severity,
                            rec.t_vulndata.f_cvss_score,
                            rec.t_vulndata.f_title,
                            ecount,
                         ] )
            vulnlist[rec.t_vulndata.f_vulnid] = vstats

    return vulnlist
예제 #14
0
def vulnlist(query="%", hostfilter=None):
    """
    Returns a vulnerability dictionary with counts:

    { 'vulnerability id': [ status, count, severity, cvss ] }
    """

    db = current.globalenv['db']
    session = current.globalenv['session']

    status = db.t_service_vulns.f_status
    svcv_id = db.t_service_vulns.id
    vulnid = db.t_vulndata.id
    f_vulnid = db.t_vulndata.f_vulnid
    sev = db.t_vulndata.f_severity
    cvss = db.t_vulndata.f_cvss_score

    hostfilter = hostfilter or session.hostfilter

    if hostfilter is None:
        # if no filter is set then we blank it out
        if session.hostfilter is None:
            session.hostfilter = [(None, None), False]

    query = (db.t_vulndata.f_vulnid.contains(query))
    query &= (db.t_service_vulns.f_services_id == db.t_services.id) & (db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)
    query = create_hostfilter_query(hostfilter, query, 't_services')
    #query = (db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)

    vulnlist = {}
    for rec in db(query).select(status, vulnid, f_vulnid, svcv_id, sev, cvss):
        q2 = (query & ((db.t_service_vulns.f_vulndata_id == rec.t_vulndata.id) &
             (db.t_service_vulns.f_status == rec.t_service_vulns.f_status)))
        count = db(q2).count()
        vstats = vulnlist.setdefault(rec.t_vulndata.f_vulnid, list())
        if rec.t_service_vulns.f_status not in map(lambda a:a[0], vstats):
            vstats.append([rec.t_service_vulns.f_status,
                            count,
                            rec.t_vulndata.f_severity,
                            rec.t_vulndata.f_cvss_score
                         ] )
            vulnlist[rec.t_vulndata.f_vulnid] = vstats

    return vulnlist
예제 #15
0
def new_service_vulns():
    # server-side processing of service vulns.. faster..better?
    # TODO: This...?
    response.title = "%s :: Services and Vulnerabilities" % (settings.title)
    if request.extension == 'json':
        if session.hostfilter is None:
            session.hostfilter = [(None, None), False]

        query = (db.t_service_vulns.id > 0) & (db.t_service_vulns.f_services_id == db.t_services.id) & (db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)
        query = create_hostfilter_query(session.hostfilter, query, 't_services')

        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)

        if request.vars.has_key('sSearch'):
            # sSearch global search box
            query &= db.t_vulndata.f_vulnid.like("%%%s%%" % request.vars.sSearch) | db.t_vulndata.f_title.like("%%%s%%" % request.vars.sSearch)

        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 = ( None,
                     db.t_vulndata.id,
                     db.t_vulndata.f_vulnid,
                     db.t_vulndata.f_title,
                     db.t_vulndata.f_severity,
                     None,
                     db.t_vulndata.f_cvss_score
                     )
예제 #16
0
def new_service_vulns():
    # server-side processing of service vulns.. faster..better?
    # TODO: This...?
    response.title = "%s :: Services and Vulnerabilities" % (settings.title)
    if request.extension == 'json':
        if session.hostfilter is None:
            session.hostfilter = [(None, None), False]

        query = (db.t_service_vulns.id > 0) & (
            db.t_service_vulns.f_services_id == db.t_services.id) & (
                db.t_service_vulns.f_vulndata_id == db.t_vulndata.id)
        query = create_hostfilter_query(session.hostfilter, query,
                                        't_services')

        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)

        if request.vars.has_key('sSearch'):
            # sSearch global search box
            query &= db.t_vulndata.f_vulnid.like(
                "%%%s%%" % request.vars.sSearch) | db.t_vulndata.f_title.like(
                    "%%%s%%" % request.vars.sSearch)

        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 = (None, db.t_vulndata.id, db.t_vulndata.f_vulnid,
                    db.t_vulndata.f_title, db.t_vulndata.f_severity, None,
                    db.t_vulndata.f_cvss_score)
예제 #17
0
파일: report.py 프로젝트: j4schur/Kvasir
def customer_xml():
    """
    Generates an XML file suitable for Customer usage
    """

    from lxml import etree

    location_attribute = '{%s}noNameSpaceSchemaLocation' % "http://www.w3.org/2001/XMLSchema-instance"
    kvasir_results_xml = etree.Element('KvasirResults',
                                       attrib={
                                           location_attribute: 'kvasir.xsd',
                                       })

    summary_xml = etree.SubElement(kvasir_results_xml, 'summary')
    customer = etree.SubElement(summary_xml, 'customer')
    customer.text = settings.customer or 'CUSTOMER NAME'
    assessment = etree.SubElement(summary_xml, 'assessment')
    assessment.set('type', settings.assessment_type)
    start_date = etree.SubElement(assessment, 'start-date')
    start_date.text = settings.start_date or 'START DATE'
    end_date = etree.SubElement(assessment, 'end-date')
    end_date.text = settings.end_date or 'END DATE'

    hosts_xml = etree.SubElement(kvasir_results_xml, 'hosts')
    os_xml = etree.SubElement(kvasir_results_xml, 'os_records')
    vulns_xml = etree.SubElement(kvasir_results_xml, 'vulns')

    # this is a little hack to ensure a record is either blank or None
    # use it as "if variable not in notin:"
    notin = [None, '']
    unknown_cpeid_counter = 0

    # go through each host, adding the os, services and vulns accordingly
    query = create_hostfilter_query(session.hostfilter)
    for host_rec in db(query).select():
        host_xml = etree.SubElement(hosts_xml, 'host')
        host_xml.set('ipaddr', host_rec.f_ipaddr)
        host_xml.set('assetgroup', host_rec.f_asset_group)
        if host_rec.f_macaddr:
            host_xml.set('macaddr', host_rec.f_macaddr)
        if host_rec.f_hostname:
            host_xml.set('hostname', host_rec.f_hostname.decode('utf-8'))
        if host_rec.f_netbios_name:
            host_xml.set('netbios', host_rec.f_netbios_name.decode('utf-8'))

        # build the os information using the highest certainty record
        highest = (0, None)
        for os_rec in db(db.t_host_os_refs.f_hosts_id == host_rec.id).select():
            if os_rec.f_certainty > highest[0]:
                highest = (os_rec.f_certainty, os_rec)

        if highest[0] > 0:
            # add os element to the host
            record = highest[1]
            os = etree.SubElement(host_xml, 'os')
            os.set('certainty', str(highest[0]))
            if record.f_class not in notin:
                os.set('class', record.f_class)
            if record.f_family not in notin:
                os.set('family', record.f_family)

            # since some os records may not have a cpe id we'll mask them with
            # using their title, replacing spaces with underscores
            t_os_rec = db.t_os[record.f_os_id]
            if t_os_rec.f_cpename in notin:
                cpeid = t_os_rec.f_title.replace(' ', '_')
            else:
                cpeid = t_os_rec.f_cpename

            os.set('id', cpeid)

            # if the id isn't in os_records, add it
            if len(os_xml.findall('.//os[@id="%s"]' %
                                  (os.get('id', None)))) < 1:
                os_info_xml = etree.SubElement(os_xml, 'os')
                os_rec = db.t_os[highest[1].f_os_id]
                os_info_xml.set('id', cpeid)
                os_info_xml.set('title', os_rec.f_title)

                if os_rec.f_vendor not in notin:
                    vendor = etree.SubElement(os_info_xml, 'vendor')
                    vendor.text = os_rec.f_vendor

                if os_rec.f_product not in notin:
                    product = etree.SubElement(os_info_xml, 'product')
                    product.text = os_rec.f_product

                if os_rec.f_version not in notin:
                    version = etree.SubElement(os_info_xml, 'version')
                    version.text = os_rec.f_version

                if os_rec.f_update not in notin:
                    update = etree.SubElement(os_info_xml, 'update')
                    update.text = os_rec.f_update

                if os_rec.f_edition not in notin:
                    edition = etree.SubElement(os_info_xml, 'edition')
                    edition.text = os_rec.f_edition

                if os_rec.f_language not in notin:
                    language = etree.SubElement(os_info_xml, 'language')
                    language.text = os_rec.f_language

        # snmp strings
        snmp_recs = db(db.t_snmp.f_hosts_id == host_rec.id).select()
        if len(snmp_recs) > 0:
            snmp_top_xml = etree.SubElement(hosts_xml, 'snmps')
            for record in snmp_recs:
                snmp_xml = etree.SubElement(snmp_top_xml, 'snmp')
                if record.f_community not in notin:
                    snmp_xml.set('community',
                                 record.f_community.decode('utf-8'))
                    snmp_xml.set('version', record.f_version)
                    snmp_xml.set('access', record.f_access)

        # netbios information
        netb_record = db(
            db.t_netbios.f_hosts_id == host_rec.id).select().first() or None
        if netb_record:
            netbios_xml = etree.SubElement(hosts_xml, 'netbios')
            if netb_record.f_type not in notin:
                netbios_xml.set('type', netb_record.f_type)
            if netb_record.f_domain not in notin:
                netbios_xml.set('domain', netb_record.f_domain.decode('utf-8'))
            if netb_record.f_lockout_limit not in notin:
                netbios_xml.set('lockout_limit',
                                str(netb_record.f_lockout_limit))
            if netb_record.f_lockout_duration not in notin:
                netbios_xml.set('lockout_duration',
                                str(netb_record.f_lockout_duration))

            if netb_record.f_advertised_names is not None:
                adv_names_xml = etree.SubElement(netbios_xml,
                                                 'advertised_names')
                for name in netb_record.f_advertised_names:
                    name_xml = etree.SubElement(adv_names_xml, 'name')
                    name.text = name.decode('utf-8')

        # build the services and vulnerabilities
        services_xml = etree.SubElement(host_xml, 'services')
        for svc_rec in db(db.t_services.f_hosts_id == host_rec.id).select():
            service_xml = etree.SubElement(services_xml, 'service')
            service_xml.set('proto', svc_rec.f_proto)
            service_xml.set('number', svc_rec.f_number)

            if svc_rec.f_name not in notin:
                name = etree.SubElement(service_xml, 'name')
                name.text = svc_rec.f_name.decode('utf-8')

            if svc_rec.f_banner not in notin:
                banner = etree.SubElement(service_xml, 'banner')
                banner.text = svc_rec.f_banner.decode('utf-8')

            # service configuration records
            svc_info_recs = db(
                db.t_service_info.f_services_id == svc_rec.id).select()
            if len(svc_info_recs) > 0:
                config_xml = etree.SubElement(service_xml, 'configuration')
                for info_rec in svc_info_recs:
                    rec_xml = etree.SubElement(config_xml, 'config')
                    if info_rec.f_name not in notin:
                        rec_xml.set('name', info_rec.f_name)
                        if info_rec.f_text not in notin:
                            rec_xml.text = info_rec.f_text.decode('utf-8')

            # vulnerabilities
            svc_vuln_recs = db(
                db.t_service_vulns.f_services_id == svc_rec.id).select()
            if len(svc_vuln_recs) > 0:
                svc_vulns_xml = etree.SubElement(service_xml, 'vulns')
                for vuln_rec in svc_vuln_recs:
                    vuln_xml = etree.SubElement(svc_vulns_xml, 'vuln')
                    vuln_xml.set('status', vuln_rec.f_status)
                    vuln_xml.set(
                        'id', db.t_vulndata[vuln_rec.f_vulndata_id].f_vulnid)
                    proof = etree.SubElement(vuln_xml, 'proof')
                    proof.text = etree.CDATA(
                        unicode(MARKMIN(vuln_rec.f_proof).xml(), 'utf-8'))

                    # search for the nexpose id in vulns_xml
                    if len(
                            vuln_xml.findall('.//vuln[@id="%s"]' %
                                             vuln_xml.get('id', None))) < 1:
                        new_vuln_xml = etree.SubElement(vulns_xml, 'vuln')
                        vulndata = db.t_vulndata[vuln_rec.f_vulndata_id]
                        new_vuln_xml.set('id', vulndata.f_vulnid)
                        new_vuln_xml.set('title', vulndata.f_title)
                        new_vuln_xml.set('severity', str(vulndata.f_severity))
                        new_vuln_xml.set('pci_sev', str(vulndata.f_pci_sev))
                        new_vuln_xml.set('cvss_score',
                                         str(vulndata.f_cvss_score))
                        new_vuln_xml.set('cvss_metric', cvss_metrics(vulndata))
                        description = etree.SubElement(new_vuln_xml,
                                                       'description')
                        description.text = etree.CDATA(
                            unicode(
                                MARKMIN(vulndata.f_description).xml(),
                                'utf-8'))
                        solution = etree.SubElement(new_vuln_xml, 'solution')
                        solution.text = etree.CDATA(
                            unicode(
                                MARKMIN(vulndata.f_solution).xml(), 'utf-8'))

                        # find vulnerability references and add them
                        vuln_refs = db(db.t_vuln_references.f_vulndata_id ==
                                       vulndata.id).select()
                        if len(vuln_refs) > 0:
                            refs_xml = etree.SubElement(
                                new_vuln_xml, 'references')
                            for ref_rec in vuln_refs:
                                record = db.t_vuln_refs[ref_rec.f_vuln_ref_id]
                                ref_xml = etree.SubElement(
                                    refs_xml, 'reference')
                                ref_xml.set('source', record.f_source)
                                ref_xml.text = record.f_text.decode('utf-8')

            # accounts
            accounts = db(db.t_accounts.f_services_id == svc_rec.id).select()
            if len(accounts) > 0:
                accounts_xml = etree.SubElement(service_xml, 'accounts')
                for acct_rec in accounts:
                    acct_xml = etree.SubElement(accounts_xml, 'account')

                    if acct_rec.f_username not in notin:
                        elem = etree.SubElement(acct_xml, 'username')
                        elem.text = acct_rec.f_username.decode('utf-8')

                    if acct_rec.f_fullname not in notin:
                        elem = etree.SubElement(acct_xml, 'fullname')
                        elem.text = acct_rec.f_fullname.decode('utf-8')

                    if acct_rec.f_password not in notin:
                        elem = etree.SubElement(acct_xml, 'password')
                        elem.text = acct_rec.f_password.decode('utf-8')

                    if acct_rec.f_hash1 not in notin:
                        elem = etree.SubElement(acct_xml, 'hash1')
                        elem.text = acct_rec.f_hash1

                    if acct_rec.f_hash1_type not in notin:
                        elem = etree.SubElement(acct_xml, 'hash1_type')
                        elem.text = acct_rec.f_hash1_type

                    if acct_rec.f_hash2 not in notin:
                        elem = etree.SubElement(acct_xml, 'hash2')
                        elem.text = acct_rec.f_hash2

                    if acct_rec.f_hash2_type not in notin:
                        elem = etree.SubElement(acct_xml, 'hash2_type')
                        elem.text = acct_rec.f_hash2_type

                    if acct_rec.f_uid not in notin:
                        elem = etree.SubElement(acct_xml, 'uid')
                        elem.text = acct_rec.f_uid

                    if acct_rec.f_gid not in notin:
                        elem = etree.SubElement(acct_xml, 'gid')
                        elem.text = acct_rec.f_gid

                    if acct_rec.f_level not in notin:
                        elem = etree.SubElement(acct_xml, 'level')
                        elem.text = acct_rec.f_level

                    if acct_rec.f_domain not in notin:
                        elem = etree.SubElement(acct_xml, 'domain')
                        elem.text = acct_rec.f_domain.decode('utf-8')

                    if acct_rec.f_description not in notin:
                        elem = etree.SubElement(acct_xml, 'description')
                        elem.text = acct_rec.f_description.decode('utf-8')

    result = etree.tostring(kvasir_results_xml,
                            pretty_print=True,
                            encoding=unicode)
    return result
예제 #18
0
def hosts_with_port():
    """
    Creates a CSV file of ipv4,ipv6 for hosts with a user-specified
    tcp/udp port
    """

    # XXX: This is broken and needs some TLC

    # buld the dropdown user list
    #users = db(db.auth_user).select()
    #userlist = []
    #for user in users:
    #    userlist.append( [ user.id, user.username ] )

    form = SQLFORM.factory(
        Field('f_proto', 'string', label=T('Protocol'), default="tcp", requires=IS_IN_SET(("tcp", "udp", "info"))),
        Field('f_number', type='string', label=T('Port')),
        Field('f_name', type='string', label=T('Name (exact)')),
        Field('f_banner', type='string', label=T('Banner (contains)')),
        Field('ignore_filter', type='boolean', default=False, label=T('Ignore Hostfilter')),
        #Field('f_ipaddr', type='boolean', default=True, label=T('Show IP Address')),
        #Field('f_hostname', type='boolean', default=False, label=T('Show Hostname')),
        #Field('f_engineer', type='integer', label=T('Engineer'), default=auth.user.id, requires=IS_IN_SET(userlist)),
        #Field('f_asset_group', type='string', label=T('Asset Group'), requires=IS_NOT_EMPTY()),
        _action=URL(request.application,'services','hosts_with_port.csv'),
    )

    db_svcs = db.t_services
    db_hosts = db.t_hosts
    if form.accepts(request.vars, session):
        q = (db_svcs.id > 0)
        q1 = None
        if form.vars.f_number:
            q1 = (db_svcs.f_number == form.vars.f_number)
        if form.vars.f_proto:
            q2 = (db_svcs.f_proto == form.vars.f_proto)
            if q1:
                q1 = q1 & q2
        if form.vars.f_name:
            q2 = (db_svcs.f_name == form.vars.f_name)
            if q1:
                q1 = q1 & q2
        if form.vars.f_banner:
            q2 = (db_svcs.f_banner.contains(form.vars.f_banner))
            if q1:
                q1 = q1 & q2

        if q1:
            q = q & q1

        if not form.vars.ignore_filter:
            q = create_hostfilter_query(session.hostfilter, q, 't_services')
        else:
            q &= (db_svcs.f_hosts_id == db_hosts.id)

        ip_list = db(q).select(db_hosts.f_ipaddr, db_svcs.f_number, db_hosts.f_hostname, cache=(cache.ram, 60))

        return dict(
            ip_list=ip_list,
        )
    elif form.errors:
        response.flash = 'Error in form'
        redirect(URL('hosts_with_port', extension=''))

    return dict(form=form)
예제 #19
0
def list():
    from skaldship.general import severity_mapping
    response.title = "%s :: Services" % (settings.title)

    if request.extension == 'json':

        q = (db.t_services.id > 0)
        proto = request.vars.f_proto
        pnum = request.vars.f_number
        if pnum:
            q &= (db.t_services.f_number == pnum)
        if proto:
            q &= (db.t_services.f_protocol == proto)

        q = create_hostfilter_query(session.hostfilter, q, 't_services')

        # Datatables Server-side: http://datatables.net/usage/server-side
        if request.vars.has_key('iDisplayStart'):
            start = int(request.vars.iDisplayStart)
        else:
            start = 0
        if request.vars.has_key('iDisplayLength'):
            if request.vars.iDisplayLength == '-1':
                limit = db(q).count()
            else:
                limit = start + int(request.vars.iDisplayLength)
        else:
            limit = int(auth.user.f_show_size)

        srch_data = request.vars.get('sSearch')
        if srch_data:
            # sSearch global search box

            # parse the search into fields (port:num proto:tcp etc)
            srch_vals = [
                ["port", db.t_services.f_number],
                ["proto", db.t_services.f_proto],
                ["status", db.t_services.f_status],
                ["name", db.t_services.f_name],
                ["banner", db.t_services.f_banner],
                ["ip", db.t_hosts.f_ipaddr],
                ["hostname", db.t_hosts.f_hostname],
            ]

            parsed = False
            for val in srch_vals:
                srch_str = "%s:(?P<f>\w+)" % val[0]
                srch_res = re.findall(srch_str, srch_data)
                for res in srch_res:
                    parsed = True
                    if val[0] == 'banner':
                        q &= (val[1].contains(res))
                    else:
                        q &= (val[1].upper() == res.upper())

            if not parsed:
                q &= db.t_services.f_proto.like("%%%s%%" % request.vars.sSearch) | \
                    db.t_services.f_number.like("%%%s%%" % request.vars.sSearch) | \
                    db.t_services.f_name.like("%%%s%%" % request.vars.sSearch) | \
                    db.t_services.f_banner.like("%%%s%%" % request.vars.sSearch) | \
                    db.t_services.f_status.like("%%%s%%" % request.vars.sSearch)

        if request.vars.iSortingCols == '1':
            cols = (
                None,
                None,
                None,
                db.t_services.f_hosts_id,
                db.t_services.f_proto,
                db.t_services.f_number,
                db.t_services.f_status,
                None,
                None,
                None,
                None,
                db.t_services.f_name,
                db.t_services.f_banner,
            )

            orderby = cols[int(request.vars.iSortCol_0)]
            if request.vars.sSortDir_0 == 'asc':
                rows=db(q).select(orderby=orderby, limitby=(start, limit))
            else:
                rows=db(q).select(orderby=~orderby, limitby=(start, limit))
        else:
            rows=db(q).select(limitby=(start, limit))

        nolimit = db(q).count()

        aaData = []

        # datatable formatting is specific
        # gather all the vulndata and exploits into a big row
        # later we'll do a find(lambda: row: row.<db>.<field> == <value>)
        # to slice it into the bits we need. Maybe it'll be faster?
        #vulndata = db().select(db.t_vulndata.f_vulnid, db.t_vulndata.id, db.t_exploit_references.f_exploit_id,
        #                       left=db.t_exploit_references.on(db.t_vulndata.id==db.t_exploit_references.f_vulndata_id))

        for r in rows:
            atxt = {}
            vulncount = 0
            vulns = db(db.t_service_vulns.f_services_id==r.t_services.id).select(db.t_service_vulns.f_vulndata_id, cache=(cache.ram, 60))

            vulnlist = []
            explist=[]
            for vuln in vulns:
                vuln_rec = db.t_vulndata[vuln.f_vulndata_id]
                if vuln_rec.f_vulnid not in vulnlist:
                    if settings.use_cvss:
                        vulnlist.append((vuln_rec.f_vulnid, vuln_rec.f_cvss_score))
                    else:
                        vulnlist.append((vuln_rec.f_vulnid, vuln_rec.f_severity))
                exploits = db(db.t_exploit_references.f_vulndata_id == vuln.f_vulndata_id).select(cache=(cache.ram, 60))
                if len(exploits) > 0:
                    for expinfo in exploits:
                        exp = db.t_exploits[expinfo.f_exploit_id]
                        exp_link = A(exp.f_name, _href=URL('exploits', 'edit', extension='html', args=exp.id), _target='blank')
                        explist.append(TR(TD(exp_link),
                                          TD(exp.f_title),
                                          TD(exp.f_source),
                                          TD(exp.f_rank)
                                          )  )

            q = r.t_services.t_service_info.select(cache=(cache.ram, 60))
            if (len(q) > 0) or (len(explist) > 0) or (len(vulnlist) > 0):
                atxt['0'] = IMG(_src=URL(request.application,'static','images/details_open.png')).xml()
            else:
                atxt['0'] = ""
            atxt['1'] = A("edit", _target="services_edit_%s" % (r.t_services.id), _href=URL('edit', args=[r.t_services.id], extension='html')).xml()
            if len(q) > 0:
                addl = []
                for svcinfo in q:
                    addl.append(TR(TD(svcinfo.f_name), TD(svcinfo.f_text)))
                atxt['2'] = TABLE(THEAD(TR(TH(T('Name')),
                                           TH(T('Text')))),
                                  TBODY(addl),
                                  _class="table table-condensed table-striped",
                                  _style="width:100%").xml()
            else:
                atxt['2'] = ''
            host_rec = db.t_hosts[r.t_services.f_hosts_id]
            atxt['3'] = host_a_maker(host_rec).xml(),
            atxt['4'] = r.t_services.f_proto

            # Append A tags around services with HTTP Ports
            if r.t_services.f_number in HTTP_PORTS and r.t_services.f_proto == "tcp" or r.t_services.f_name == "HTTP":
                atxt['5'] = A(r.t_services.f_number,
                              _href=URL('default', 'redirect', extension='html', vars={'url': "http://%s:%s/" % (host_rec.f_ipaddr, r.t_services.f_number)}),
                              _target="%s-tcp-%s" % (host_rec.f_ipaddr, r.t_services.f_number)).xml()
            elif r.t_services.f_number in HTTPS_PORTS and r.t_services.f_proto == "tcp" or r.t_services.f_name == "HTTPS":
                atxt['5'] = A(r.t_services.f_number,
                              _href=URL('default', 'redirect', extension='html', vars={'url': "https://%s:%s/" % (host_rec.f_ipaddr, r.t_services.f_number)}),
                              _target="%s-tcp-%s" % (host_rec.f_ipaddr, r.t_services.f_number)).xml()
            else:
                atxt['5'] = r.t_services.f_number

            atxt['6'] = r.t_services.f_status
            atxt['7'] = len(vulnlist)
            vulntxt = []
            for vuln in vulnlist:
                color = severity_mapping(vuln[1])[2]
                vulntxt.append(A(vuln[0], _id="vuln", _target="vulninfo_by_vulnid_%s" % (vuln[0]), _href=URL('vulns', 'vulninfo_by_vulnid', args=[vuln[0]], extension='html'),
                                 _style="color:"+color).xml())
            atxt['8'] = " :: ".join(vulntxt)
            if len(explist) > 0:
                atxt['9'] = "Yes (%d)" % (len(explist))
            else:
                atxt['9'] = ''
            if len(explist) > 0:
                atxt['10'] = TABLE(THEAD(TR(TH(T('Name')),
                                           TH(T('Title')),
                                           TH(T('Source')),
                                           TH(T('Rank')))),
                                  TBODY(explist),
                                  _class="table table-condensed",
                                  _style="width:100%").xml()
            else:
                atxt['10'] = ''
            atxt['11'] = r.t_services.f_name
            atxt['12'] = r.t_services.f_banner
            atxt['DT_RowId'] = r.t_services.id

            aaData.append(atxt)

        result = {
            'sEcho': request.vars.sEcho,
            'iTotalRecords': db(db.t_services).count(),
            'iTotalDisplayRecords': nolimit,
            'aaData': aaData,
        }

        return result
    else:
        add = AddModal(
            db.t_services, 'Add', 'Add', 'Add Service',
            #fields=[
            #    'f_proto', 'f_number', 'f_status', 'f_name', 'f_banner'
            #],
            cmd='servicetable.fnReloadAjax();'
        )
        db.t_services.id.comment = add.create()
        return dict(add=add)
예제 #20
0
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)
예제 #21
0
파일: accounts.py 프로젝트: kimdane/Kvasir
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)
예제 #22
0
def hosts_with_port():
    """
    Creates a CSV file of ipv4,ipv6 for hosts with a user-specified
    tcp/udp port
    """

    # XXX: This is broken and needs some TLC

    # buld the dropdown user list
    #users = db(db.auth_user).select()
    #userlist = []
    #for user in users:
    #    userlist.append( [ user.id, user.username ] )

    form = SQLFORM.factory(
        Field('f_proto',
              'string',
              label=T('Protocol'),
              default="tcp",
              requires=IS_IN_SET(("tcp", "udp", "info"))),
        Field('f_number', type='string', label=T('Port')),
        Field('f_name', type='string', label=T('Name (exact)')),
        Field('f_banner', type='string', label=T('Banner (contains)')),
        Field('ignore_filter',
              type='boolean',
              default=False,
              label=T('Ignore Hostfilter')),
        #Field('f_ipaddr', type='boolean', default=True, label=T('Show IP Address')),
        #Field('f_hostname', type='boolean', default=False, label=T('Show Hostname')),
        #Field('f_engineer', type='integer', label=T('Engineer'), default=auth.user.id, requires=IS_IN_SET(userlist)),
        #Field('f_asset_group', type='string', label=T('Asset Group'), requires=IS_NOT_EMPTY()),
        _action=URL(request.application, 'services', 'hosts_with_port.csv'),
    )

    db_svcs = db.t_services
    db_hosts = db.t_hosts
    if form.accepts(request.vars, session):
        q = (db_svcs.id > 0)
        q1 = None
        if form.vars.f_number:
            q1 = (db_svcs.f_number == form.vars.f_number)
        if form.vars.f_proto:
            q2 = (db_svcs.f_proto == form.vars.f_proto)
            if q1:
                q1 = q1 & q2
        if form.vars.f_name:
            q2 = (db_svcs.f_name == form.vars.f_name)
            if q1:
                q1 = q1 & q2
        if form.vars.f_banner:
            q2 = (db_svcs.f_banner.contains(form.vars.f_banner))
            if q1:
                q1 = q1 & q2

        if q1:
            q = q & q1

        if not form.vars.ignore_filter:
            q = create_hostfilter_query(session.hostfilter, q, 't_services')
        else:
            q &= (db_svcs.f_hosts_id == db_hosts.id)

        ip_list = db(q).select(db_hosts.f_ipaddr,
                               db_svcs.f_number,
                               db_hosts.f_hostname,
                               cache=(cache.ram, 60))

        return dict(ip_list=ip_list, )
    elif form.errors:
        response.flash = 'Error in form'
        redirect(URL('hosts_with_port', extension=''))

    return dict(form=form)
예제 #23
0
def list():
    from skaldship.general import severity_mapping
    response.title = "%s :: Services" % (settings.title)

    if request.extension == 'json':

        q = (db.t_services.id > 0)
        proto = request.vars.f_proto
        pnum = request.vars.f_number
        if pnum:
            q &= (db.t_services.f_number == pnum)
        if proto:
            q &= (db.t_services.f_protocol == proto)

        q = create_hostfilter_query(session.hostfilter, q, 't_services')

        # Datatables Server-side: http://datatables.net/usage/server-side
        if 'iDisplayStart' in request.vars:
            start = int(request.vars.iDisplayStart)
        else:
            start = 0
        if 'iDisplayLength' in request.vars:
            if request.vars.iDisplayLength == '-1':
                limit = db(q).count()
            else:
                limit = start + int(request.vars.iDisplayLength)
        else:
            limit = int(auth.user.f_show_size)

        srch_data = request.vars.get('sSearch')
        if srch_data:
            # sSearch global search box

            # parse the search into fields (port:num proto:tcp etc)
            srch_vals = [
                ["port", db.t_services.f_number],
                ["proto", db.t_services.f_proto],
                ["status", db.t_services.f_status],
                ["name", db.t_services.f_name],
                ["banner", db.t_services.f_banner],
                ["ip", db.t_hosts.f_ipaddr],
                ["hostname", db.t_hosts.f_hostname],
            ]

            parsed = False
            for val in srch_vals:
                srch_str = "%s:(?P<f>\w+)" % val[0]
                srch_res = re.findall(srch_str, srch_data)
                for res in srch_res:
                    parsed = True
                    if val[0] == 'banner':
                        q &= (val[1].contains(res))
                    else:
                        q &= (val[1].upper() == res.upper())

            if not parsed:
                q &= db.t_services.f_proto.like("%%%s%%" % request.vars.sSearch) | \
                    db.t_services.f_number.like("%%%s%%" % request.vars.sSearch) | \
                    db.t_services.f_name.like("%%%s%%" % request.vars.sSearch) | \
                    db.t_services.f_banner.like("%%%s%%" % request.vars.sSearch) | \
                    db.t_services.f_status.like("%%%s%%" % request.vars.sSearch)

        if request.vars.iSortingCols == '1':
            cols = (
                None,
                None,
                None,
                db.t_services.f_hosts_id,
                db.t_services.f_proto,
                db.t_services.f_number,
                db.t_services.f_status,
                None,
                None,
                None,
                None,
                db.t_services.f_name,
                db.t_services.f_banner,
            )

            orderby = cols[int(request.vars.iSortCol_0)]
            if request.vars.sSortDir_0 == 'asc':
                rows = db(q).select(orderby=orderby, limitby=(start, limit))
            else:
                rows = db(q).select(orderby=~orderby, limitby=(start, limit))
        else:
            rows = db(q).select(limitby=(start, limit))

        nolimit = db(q).count()

        aaData = []

        # datatable formatting is specific
        # gather all the vulndata and exploits into a big row
        # later we'll do a find(lambda: row: row.<db>.<field> == <value>)
        # to slice it into the bits we need. Maybe it'll be faster?
        #vulndata = db().select(db.t_vulndata.f_vulnid, db.t_vulndata.id, db.t_exploit_references.f_exploit_id,
        #                       left=db.t_exploit_references.on(db.t_vulndata.id==db.t_exploit_references.f_vulndata_id))

        for r in rows:
            atxt = {}
            vulncount = 0
            vulns = db(
                db.t_service_vulns.f_services_id == r.t_services.id).select(
                    db.t_service_vulns.f_vulndata_id, cache=(cache.ram, 60))

            vulnlist = []
            explist = []
            for vuln in vulns:
                vuln_rec = db.t_vulndata[vuln.f_vulndata_id]
                if vuln_rec.f_vulnid not in vulnlist:
                    if settings.use_cvss:
                        vulnlist.append(
                            (vuln_rec.f_vulnid, vuln_rec.f_cvss_score))
                    else:
                        vulnlist.append(
                            (vuln_rec.f_vulnid, vuln_rec.f_severity))
                exploits = db(db.t_exploit_references.f_vulndata_id ==
                              vuln.f_vulndata_id).select(cache=(cache.ram, 60))
                if len(exploits) > 0:
                    for expinfo in exploits:
                        exp = db.t_exploits[expinfo.f_exploit_id]
                        exp_link = A(exp.f_name,
                                     _href=URL('exploits',
                                               'edit',
                                               extension='html',
                                               args=exp.id),
                                     _target='blank')
                        explist.append(
                            TR(TD(exp_link), TD(exp.f_title), TD(exp.f_source),
                               TD(exp.f_rank)))

            q = r.t_services.t_service_info.select(cache=(cache.ram, 60))
            if (len(q) > 0) or (len(explist) > 0) or (len(vulnlist) > 0):
                atxt['0'] = IMG(_src=URL(request.application, 'static',
                                         'images/details_open.png')).xml()
            else:
                atxt['0'] = ""
            atxt['1'] = A("edit",
                          _target="services_edit_%s" % (r.t_services.id),
                          _href=URL('edit',
                                    args=[r.t_services.id],
                                    extension='html')).xml()
            if len(q) > 0:
                addl = []
                for svcinfo in q:
                    addl.append(TR(TD(svcinfo.f_name), TD(svcinfo.f_text)))
                atxt['2'] = TABLE(THEAD(TR(TH(T('Name')), TH(T('Text')))),
                                  TBODY(addl),
                                  _class="table table-condensed table-striped",
                                  _style="width:100%").xml()
            else:
                atxt['2'] = ''
            host_rec = db.t_hosts[r.t_services.f_hosts_id]
            atxt['3'] = host_a_maker(host_rec).xml(),
            atxt['4'] = r.t_services.f_proto

            # Append A tags around services with HTTP Ports
            if r.t_services.f_number in HTTP_PORTS and r.t_services.f_proto == "tcp" or r.t_services.f_name == "HTTP":
                atxt['5'] = A(
                    r.t_services.f_number,
                    _href=URL('default',
                              'redirect',
                              extension='html',
                              vars={
                                  'url':
                                  "http://%s:%s/" %
                                  (host_rec.f_ipaddr, r.t_services.f_number)
                              }),
                    _target="%s-tcp-%s" %
                    (host_rec.f_ipaddr, r.t_services.f_number)).xml()
            elif r.t_services.f_number in HTTPS_PORTS and r.t_services.f_proto == "tcp" or r.t_services.f_name == "HTTPS":
                atxt['5'] = A(
                    r.t_services.f_number,
                    _href=URL('default',
                              'redirect',
                              extension='html',
                              vars={
                                  'url':
                                  "https://%s:%s/" %
                                  (host_rec.f_ipaddr, r.t_services.f_number)
                              }),
                    _target="%s-tcp-%s" %
                    (host_rec.f_ipaddr, r.t_services.f_number)).xml()
            else:
                atxt['5'] = r.t_services.f_number

            atxt['6'] = r.t_services.f_status
            atxt['7'] = len(vulnlist)
            vulntxt = []
            for vuln in vulnlist:
                color = severity_mapping(vuln[1])[2]
                vulntxt.append(
                    A(vuln[0],
                      _id="vuln",
                      _target="vulninfo_by_vulnid_%s" % (vuln[0]),
                      _href=URL('vulns',
                                'vulninfo_by_vulnid',
                                args=[vuln[0]],
                                extension='html'),
                      _style="color:" + color).xml())
            atxt['8'] = " :: ".join(vulntxt)
            if len(explist) > 0:
                atxt['9'] = "Yes (%d)" % (len(explist))
            else:
                atxt['9'] = ''
            if len(explist) > 0:
                atxt['10'] = TABLE(THEAD(
                    TR(TH(T('Name')), TH(T('Title')), TH(T('Source')),
                       TH(T('Rank')))),
                                   TBODY(explist),
                                   _class="table table-condensed",
                                   _style="width:100%").xml()
            else:
                atxt['10'] = ''
            atxt['11'] = r.t_services.f_name
            atxt['12'] = r.t_services.f_banner
            atxt['DT_RowId'] = r.t_services.id

            aaData.append(atxt)

        result = {
            'sEcho': request.vars.sEcho,
            'iTotalRecords': db(db.t_services).count(),
            'iTotalDisplayRecords': nolimit,
            'aaData': aaData,
        }

        return result
    else:
        add = AddModal(
            db.t_services,
            'Add',
            'Add',
            'Add Service',
            #fields=[
            #    'f_proto', 'f_number', 'f_status', 'f_name', 'f_banner'
            #],
            cmd='servicetable.fnReloadAjax();')
        db.t_services.id.comment = add.create()
        return dict(add=add)
예제 #24
0
파일: report.py 프로젝트: kimdane/Kvasir
def report():
    """
    Genereate a HTML-report with fields from statistics, hosts, vulns, and summaries from the wiki
    """

    statistics = db_statistics()
    adv_stats = adv_db_statistics()
    graphs = graphs_index()

    customer = settings.customer
    assessment = settings.assessment_typed
    start_date = settings.start_date or 'START DATE'
    end_date = settings.end_date or 'END DATE'

    # grab the filter type and value if provided or from the session
    if session.hostfilter is None:
        f_type  = request.vars.f_type or None
        f_value = request.vars.f_value or None
    else:
        f_type  = session.hostfilter[0]
        f_value = session.hostfilter[1]

    # this is a little hack to ensure a record is either blank or None
    # use it as "if variable not in notin:"
    notin = [ None, '' ]
    unknown_cpeid_counter = 0

    hosts = []
    vulnerabilities = {}
    # go through each host, adding the os, services and vulns accordingly
    query = create_hostfilter_query([(f_type, f_value), False])
    for host_rec in db(query).select():
        host = {}
        host['ipv4'] = host_rec.f_ipv4
        host['asset_group'] = host_rec.f_asset_group
        if host_rec.f_ipv6:
            host['ipv6'] = host_rec.f_ipv6
        if host_rec.f_macaddr:
            host['macaddr'] = host_rec.f_macaddr
        if host_rec.f_hostname:
            host['hostname'] = host_rec.f_hostname.decode('utf-8')
        if host_rec.f_netbios_name:
            host['netbios_name'] = host_rec.f_netbios_name.decode('utf-8')

        # build the os information using the highest certainty record
        highest = (0, None)
        for os_rec in db(db.t_host_os_refs.f_hosts_id == host_rec.id).select():
            if os_rec.f_certainty > highest[0]:
                highest = (os_rec.f_certainty, os_rec)

        if highest[0] > 0:
            # add os element to the host
            record = highest[1]
            host['os']=record
            host['os']['certainty'] = str(highest[0])
            if record.f_class not in notin:
                host['os']['class'] = record.f_class
            if record.f_family not in notin:
                host['os']['family'] = record.f_family

            # since some os records may not have a cpe id we'll mask them with
            # using their title, replacing spaces with underscores
            t_os_rec = db.t_os[record.f_os_id]
            if t_os_rec.f_cpename in notin:
                cpeid = t_os_rec.f_title.replace(' ', '_')
            else:
                cpeid = t_os_rec.f_cpename

            host['os']['id'] = cpeid

            # if the id isn't in os_records, add it
            # if 1:
            #     os_rec = db.t_os[highest[1].f_os_id]
            #     host['os']['id'] = cpeid
            #     host['os']['title'] = os_rec.f_title
            #
            #     if os_rec.f_vendor not in notin:
            #         host['os']['vendor'] = os_rec.f_vendor
            #
            #     if os_rec.f_product not in notin:
            #         host['os']['product'] = os_rec.f_product
            #
            #     if os_rec.f_version not in notin:
            #         host['os']['version'] = os_rec.f_version
            #
            #     if os_rec.f_update not in notin:
            #         host['os']['update'] = os_rec.f_update
            #
            #     if os_rec.f_edition not in notin:
            #         host['os']['edition'] = os_rec.f_edition
            #
            #     if os_rec.f_language not in notin:
            #         host['os']['language'] = os_rec.f_language

        # snmp strings
        snmp_recs = db(db.t_snmp.f_hosts_id == host_rec.id).select()
        if len(snmp_recs) > 0:
            host['snmps'] = []
            for record in snmp_recs:
                snmp = {}
                if record.f_community not in notin:
                    snmp['community'] = record.f_community.decode('utf-8')
                    snmp['version'] = record.f_version
                    snmp['access'] = record.f_access
                    host['snmps'].append(snmp)

        # netbios information
        netb_record = db(db.t_netbios.f_hosts_id == host_rec.id).select().first() or None
        if netb_record:
            host['netbios'] = {}
            if netb_record.f_type not in notin:
                host['netbios']['type'] =  netb_record.f_type
            if netb_record.f_domain not in notin:
                host['netbios']['domain'] =  netb_record.f_domain.decode('utf-8')
            if netb_record.f_lockout_limit not in notin:
                host['netbios']['lockout_limit'] =  str(netb_record.f_lockout_limit)
            if netb_record.f_lockout_duration not in notin:
                host['netbios']['lockout_duration'] =  str(netb_record.f_lockout_duration)

            if netb_record.f_advertised_names is not None:
                for name in netb_record.f_advertised_names:
                    host['netbios']['advertised_name'] = name.decode('utf-8')

        # build the services and vulnerabilities
        host['services'] = []
        for svc_rec in db(db.t_services.f_hosts_id == host_rec.id).select():
            service = {}
            service['proto'] = svc_rec.f_proto
            service['number'] = int(svc_rec.f_number)

            if svc_rec.f_name not in notin:
                service['name'] = svc_rec.f_name.decode('utf-8')
            else:
                service['name'] = T('unknown')

            if svc_rec.f_banner not in notin:
                service['banner'] = svc_rec.f_banner.decode('utf-8')

            # service configuration records
            svc_info_recs = db(db.t_service_info.f_services_id == svc_rec.id).select()
            if len(svc_info_recs) > 0:
                service['configs'] = []
                for info_rec in svc_info_recs:
                    config = {}
                    if info_rec.f_name not in notin:
                        config['name'] = info_rec.f_name
                        if info_rec.f_text not in notin:
                            config['text'] = info_rec.f_text.decode('utf-8')
                    service['configs'].append(config)

            # vulnerabilities
            svc_vuln_recs = db(db.t_service_vulns.f_services_id == svc_rec.id).select()
            if len(svc_vuln_recs) > 0:
                service['vulns'] = []
                for vuln_rec in svc_vuln_recs:
                    vuln = {}
                    vuln['status'] = vuln_rec.f_status
                    vuln['proof'] = vuln_rec.f_proof

                    vulndata = db.t_vulndata[vuln_rec.f_vulndata_id]
                    vuln['vulninfo'] = vulndata
                    vuln['id'] = vulndata.f_vulnid
                    vuln['title'] = vulndata.f_title
                    vuln['severity'] = str(vulndata.f_severity)
                    vuln['pci_sev'] = str(vulndata.f_pci_sev)
                    vuln['cvss_score'] = str(vulndata.f_cvss_score)
                    vuln['cvssmetrics'] = cvss_metrics(vulndata)
                    vuln['description'] = vulndata.f_description
                    vuln['solution'] = vulndata.f_solution

                    # find vulnerability references and add them
                    vuln_refs = db(db.t_vuln_references.f_vulndata_id == vulndata.id).select()
                    if len(vuln_refs) > 0:
                        vuln['refs'] = []
                        for ref_rec in vuln_refs:
                            ref = {}
                            record = db.t_vuln_refs[ref_rec.f_vuln_ref_id]
                            ref['source'] = record.f_source
                            ref['text'] = record.f_text.decode('utf-8')
                            vuln['refs'].append(ref)

                    # find vulnerability exploits and add them
                    vuln_exploits = '' #db(db.t_vuln_references.f_vulndata_id == vulndata.id).select()
                    if len(vuln_exploits) > 0:
                      vuln['exploits'] = []
                      for ref_rec in vuln_refs:
                        ref = {}
                        record = db.t_vuln_refs[ref_rec.f_vuln_ref_id]
                        ref['source'] = record.f_source
                        ref['text'] = record.f_text.decode('utf-8')
                        vuln['refs'].append(ref)

                    if (int(vuln['severity'])>0):
                      service['vulns'].append(vuln)

                      vuln['hosts'] = []
                      vulnhost = {}
                      vulnhost['ipv4'] = host['ipv4']
                      if 'hostname' in host:
                        vulnhost['hostname'] = host['hostname']
                      else:
                        vulnhost['hostname'] = host['ipv4']
                      vulnhost['svcproto'] = service['proto']
                      vulnhost['svcnumber'] = service['number']
                      vulnhost['status'] = vuln_rec.f_status
                      vulnhost['proof'] = vuln_rec.f_proof
                      vulnhost['url'] = ''
                      if svc_rec.f_name not in notin:
                          vulnhost['svcname'] = svc_rec.f_name.decode('utf-8')
                      else:
                          vulnhost['svcname'] = T('unknown')
                      if svc_rec.f_banner not in notin:
                          vulnhost['svcbanner'] = svc_rec.f_banner.decode('utf-8')
                      id = str(vuln_rec.f_vulndata_id)
                      if id not in vulnerabilities:
                          vulnerabilities[id] = vuln
                      vulnerabilities[id]['hosts'].append(vulnhost)

                if len(service['vulns']) is 0:
                  del service['vulns']

            host['services'].append(service)
            # accounts
            #accounts = db(db.t_accounts.f_services_id == svc_rec.id).select()
            # if len(accounts) > 0:
            #     host['accounts'] = []
            #
            #     for acct_rec in accounts:
            #         account = {}
            #
            #         if acct_rec.f_username not in notin:
            #             account['username'] = acct_rec.f_username.decode('utf-8')
            #
            #         if acct_rec.f_fullname not in notin:
            #             account['fullname'] = acct_rec.f_fullname.decode('utf-8')
            #
            #         if acct_rec.f_password not in notin:
            #             account['password'] = acct_rec.f_password.decode('utf-8')
            #
            #         if acct_rec.f_hash1 not in notin:
            #             account['hash1'] = acct_rec.f_hash1
            #
            #         if acct_rec.f_hash1_type not in notin:
            #             account['hash1_type'] = acct_rec.f_hash1_type
            #
            #         if acct_rec.f_hash2 not in notin:
            #             account['hash2'] = acct_rec.f_hash2
            #
            #         if acct_rec.f_hash2_type not in notin:
            #             account['hash2_type'] = acct_rec.f_hash2_type
            #
            #         if acct_rec.f_uid not in notin:
            #             account['uid'] = acct_rec.f_uid
            #
            #         if acct_rec.f_gid not in notin:
            #             account['gid'] = acct_rec.f_gid
            #
            #         if acct_rec.f_level not in notin:
            #             account['level'] = acct_rec.f_level
            #
            #         if acct_rec.f_domain not in notin:
            #             account['domain'] = acct_rec.f_domain.decode('utf-8')
            #
            #         if acct_rec.f_description not in notin:
            #             account['description'] = acct_rec.f_description.decode('utf-8')
            #         host['accounts'].append(account)
        hosts.append(host)
    #response.files.append(URL(request.application,'static','js/jquery.sparkline.js'))

    #get JSON from host.list and use mockjax
    ext = request.extension
    request.extension = 'json'
    hostlist = list() #Not an empty list
    request.extension = ext
    #remove the engineer field from the customers report
    hostlist['aaData'][-1]['10']=None
    import re
    hostlist = re.sub("href=\"[^>]*>([^<]*)","href=\"#\\1\">\\1", str(hostlist))
    listjson=hostlist.replace('\"','\\\"').replace('\'','\"').replace('L, ',', ').replace('None','null')
    vulnlst=sorted(vulnerabilities, key=lambda x: int(vulnerabilities[x]['severity']), reverse=True)
    return dict(
    vulnlst=vulnlst,
    vulnerabilities=vulnerabilities,
    statistics=statistics,
    adv_stats=adv_stats,
    graphs=graphs,
    hosts=hosts,
    hostfilter=session.hostfilter,
    listjson=listjson)
예제 #25
0
def vulninfo_by_vulnid():
    """
    Returns the vulnerablilty details
    """
    if request.args(0) is None:
        redirect(URL('default', 'error', vars={'msg': T('No Vulnerability ID sent')}))

    record = db(db.t_vulndata.f_vulnid==request.args(0)).select().first()
    if record is not None:
        # grab vuln references and format the table
        response.title = "%s :: Vulnerability Popup :: %s" % (settings.title, record.f_vulnid)
        #cvss_metrics = "AV:%s/AC:%s/Au:%s/C:%s/I:%s/A:%s" % (record.f_cvss_av,
        #                                                     record.f_cvss_ac,
        #                                                     record.f_cvss_au,
        #                                                     record.f_cvss_c,
        #                                                     record.f_cvss_i,
        #                                                     record.f_cvss_a)

        vulninfo = record
        cvssmetrics = cvss_metrics(record)

        refs = LOAD(request.controller, 'vuln_refs_by_vulnid', args=[record.id], ajax=True)
        exploits = LOAD(request.controller, 'vuln_exploits_by_vulnid', args=[record.id], ajax=True)

        # TODO: Add hosts with vulnerability -- include service info (proto/port) and
        # ability to delete vuln from service

        query = db.t_service_vulns.f_vulndata_id == record.id
        svc_vulns = db(query).select(db.t_service_vulns.f_services_id,
                                     db.t_service_vulns.f_proof,
                                     db.t_service_vulns.f_status,
                                     db.t_service_vulns.id,
                                     distinct=True)

        hosts_tr = []
        query = (db.t_hosts.id > 0)
        query = create_hostfilter_query(session.hostfilter, query, 't_services')
        hosts_dict = db(query).select(db.t_hosts.id, cache=(cache.ram, 30)).as_dict()
        hostlist = map(lambda x: x['id'], hosts_dict.itervalues())
        for svc_vuln in svc_vulns:
            svc = db.t_services[svc_vuln.f_services_id]
            if svc is None:
                logger.error("t_servics_vuln #%s does not link to a t_services.id!" % (svc_vuln.id))
                continue

            if svc.f_hosts_id not in hostlist:
                continue

            host_rec = db.t_hosts[svc.f_hosts_id]
            hosts_tr.append(TR(TD(SPAN(I(_class="icon-trash"), _name="host_del", _id=svc_vuln.id)),
                               TD(A(IMG(_src=URL(request.application, 'static/images', 'terminal.png'),
                                        _width="20",
                                        _height="20",
                                        _style="float:left"), "  ",
                                    _href="#", _onclick="launchterm('%s')" % (host_rec.id)),
                                   host_a_maker(host_rec)),
                               TD("%s/%s" % (svc.f_proto, svc.f_number)),
                               TD(MARKMIN(svc_vuln.f_proof)),
                               TD(svc_vuln.f_status),
                               _id=svc_vuln.id ) )

        if len(hosts_tr) > 0:
            hosts = TABLE(THEAD(TR(TH(T('Del'), _width="5%"),
                                   TH(T('Host Information')),
                                   TH(T('Port')),
                                   TH(T('Proof')),
                                   TH(T('Status')),
                                )  ),
                          TBODY(hosts_tr),
                          _id="vulntable", _class="datatable", _width="100%")
        else:
            hosts = None
    else:
        response.title = "%s :: Invalid Vulnerability ID"
        return dict(vulninfo={}, refs={}, exploits={}, hosts={})

    # vuln form data
    vuln=crud.read(db.t_vulndata, record) #returns read-only for for t_vulndata
    vuln.attributes['_id'] = "vuln_record"
    return dict(vuln=vuln, vulninfo=vulninfo, cvssmetrics=cvssmetrics, refs=refs, exploits=exploits, hosts=hosts)
예제 #26
0
def customer_xml():
    """
    Generates an XML file suitable for Customer usage
    """

    from lxml import etree

    # grab the filter type and value if provided or from the session
    if session.hostfilter is None:
        f_type  = request.vars.f_type or None
        f_value = request.vars.f_value or None
    else:
        f_type  = session.hostfilter[0]
        f_value = session.hostfilter[1]

    location_attribute = '{%s}noNameSpaceSchemaLocation' % "http://www.w3.org/2001/XMLSchema-instance"
    kvasir_results_xml = etree.Element('KvasirResults', attrib={ location_attribute: 'kvasir.xsd', })

    summary_xml = etree.SubElement(kvasir_results_xml, 'summary')
    customer = etree.SubElement(summary_xml, 'customer')
    customer.text = settings.customer or 'CUSTOMER NAME'
    assessment = etree.SubElement(summary_xml, 'assessment')
    assessment.set('type', settings.assessment_type)
    start_date = etree.SubElement(assessment, 'start-date')
    start_date.text = settings.start_date or 'START DATE'
    end_date = etree.SubElement(assessment, 'end-date')
    end_date.text = settings.end_date or 'END DATE'

    hosts_xml = etree.SubElement(kvasir_results_xml, 'hosts')
    os_xml = etree.SubElement(kvasir_results_xml, 'os_records')
    vulns_xml = etree.SubElement(kvasir_results_xml, 'vulns')

    # this is a little hack to ensure a record is either blank or None
    # use it as "if variable not in notin:"
    notin = [ None, '' ]
    unknown_cpeid_counter = 0

    # go through each host, adding the os, services and vulns accordingly
    query = create_hostfilter_query([(f_type, f_value), False])
    for host_rec in db(query).select():
        host_xml = etree.SubElement(hosts_xml, 'host')
        host_xml.set('ipv4', host_rec.f_ipv4)
        host_xml.set('assetgroup', host_rec.f_asset_group)
        if host_rec.f_ipv6:
            host_xml.set('ipv6', host_rec.f_ipv6)
        if host_rec.f_macaddr:
            host_xml.set('macaddr', host_rec.f_macaddr)
        if host_rec.f_hostname:
            host_xml.set('hostname', host_rec.f_hostname.decode('utf-8'))
        if host_rec.f_netbios_name:
            host_xml.set('netbios', host_rec.f_netbios_name.decode('utf-8'))

        # build the os information using the highest certainty record
        highest = (0, None)
        for os_rec in db(db.t_host_os_refs.f_hosts_id == host_rec.id).select():
            if os_rec.f_certainty > highest[0]:
                highest = (os_rec.f_certainty, os_rec)

        if highest[0] > 0:
            # add os element to the host
            record = highest[1]
            os = etree.SubElement(host_xml, 'os')
            os.set('certainty', str(highest[0]))
            if record.f_class not in notin:
                os.set('class', record.f_class)
            if record.f_family not in notin:
                os.set('family', record.f_family)

            # since some os records may not have a cpe id we'll mask them with
            # using their title, replacing spaces with underscores
            t_os_rec = db.t_os[record.f_os_id]
            if t_os_rec.f_cpename in notin:
                cpeid = t_os_rec.f_title.replace(' ', '_')
            else:
                cpeid = t_os_rec.f_cpename

            os.set('id', cpeid)

            # if the id isn't in os_records, add it
            if len(os_xml.findall('.//os[@id="%s"]' % (os.get('id', None)))) < 1:
                os_info_xml = etree.SubElement(os_xml, 'os')
                os_rec = db.t_os[highest[1].f_os_id]
                os_info_xml.set('id', cpeid)
                os_info_xml.set('title', os_rec.f_title)

                if os_rec.f_vendor not in notin:
                    vendor = etree.SubElement(os_info_xml, 'vendor')
                    vendor.text = os_rec.f_vendor

                if os_rec.f_product not in notin:
                    product = etree.SubElement(os_info_xml, 'product')
                    product.text = os_rec.f_product

                if os_rec.f_version not in notin:
                    version = etree.SubElement(os_info_xml, 'version')
                    version.text = os_rec.f_version

                if os_rec.f_update not in notin:
                    update = etree.SubElement(os_info_xml, 'update')
                    update.text = os_rec.f_update

                if os_rec.f_edition not in notin:
                    edition = etree.SubElement(os_info_xml, 'edition')
                    edition.text = os_rec.f_edition

                if os_rec.f_language not in notin:
                    language = etree.SubElement(os_info_xml, 'language')
                    language.text = os_rec.f_language

        # snmp strings
        snmp_recs = db(db.t_snmp.f_hosts_id == host_rec.id).select()
        if len(snmp_recs) > 0:
            snmp_top_xml = etree.SubElement(hosts_xml, 'snmps')
            for record in snmp_recs:
                snmp_xml = etree.SubElement(snmp_top_xml, 'snmp')
                if record.f_community not in notin:
                    snmp_xml.set('community', record.f_community.decode('utf-8'))
                    snmp_xml.set('version', record.f_version)
                    snmp_xml.set('access', record.f_access)

        # netbios information
        netb_record = db(db.t_netbios.f_hosts_id == host_rec.id).select().first() or None
        if netb_record:
            netbios_xml = etree.SubElement(hosts_xml, 'netbios')
            if netb_record.f_type not in notin:
                netbios_xml.set('type', netb_record.f_type)
            if netb_record.f_domain not in notin:
                netbios_xml.set('domain', netb_record.f_domain.decode('utf-8'))
            if netb_record.f_lockout_limit not in notin:
                netbios_xml.set('lockout_limit', str(netb_record.f_lockout_limit))
            if netb_record.f_lockout_duration not in notin:
                netbios_xml.set('lockout_duration', str(netb_record.f_lockout_duration))

            if netb_record.f_advertised_names is not None:
                adv_names_xml = etree.SubElement(netbios_xml, 'advertised_names')
                for name in netb_record.f_advertised_names:
                    name_xml = etree.SubElement(adv_names_xml, 'name')
                    name.text = name.decode('utf-8')

        # build the services and vulnerabilities
        services_xml = etree.SubElement(host_xml, 'services')
        for svc_rec in db(db.t_services.f_hosts_id == host_rec.id).select():
            service_xml = etree.SubElement(services_xml, 'service')
            service_xml.set('proto', svc_rec.f_proto)
            service_xml.set('number', svc_rec.f_number)

            if svc_rec.f_name not in notin:
                name = etree.SubElement(service_xml, 'name')
                name.text = svc_rec.f_name.decode('utf-8')

            if svc_rec.f_banner not in notin:
                banner = etree.SubElement(service_xml, 'banner')
                banner.text = svc_rec.f_banner.decode('utf-8')

            # service configuration records
            svc_info_recs = db(db.t_service_info.f_services_id == svc_rec.id).select()
            if len(svc_info_recs) > 0:
                config_xml = etree.SubElement(service_xml, 'configuration')
                for info_rec in svc_info_recs:
                    rec_xml = etree.SubElement(config_xml, 'config')
                    if info_rec.f_name not in notin:
                        rec_xml.set('name', info_rec.f_name)
                        if info_rec.f_text not in notin:
                            rec_xml.text = info_rec.f_text.decode('utf-8')

            # vulnerabilities
            svc_vuln_recs = db(db.t_service_vulns.f_services_id == svc_rec.id).select()
            if len(svc_vuln_recs) > 0:
                svc_vulns_xml = etree.SubElement(service_xml, 'vulns')
                for vuln_rec in svc_vuln_recs:
                    vuln_xml = etree.SubElement(svc_vulns_xml, 'vuln')
                    vuln_xml.set('status', vuln_rec.f_status)
                    vuln_xml.set('id', db.t_vulndata[vuln_rec.f_vulndata_id].f_vulnid)
                    proof = etree.SubElement(vuln_xml, 'proof')
                    proof.text = etree.CDATA(unicode(MARKMIN(vuln_rec.f_proof).xml(), 'utf-8'))

                    # search for the nexpose id in vulns_xml
                    if len(vuln_xml.findall('.//vuln[@id="%s"]' % vuln_xml.get('id', None))) < 1:
                        new_vuln_xml = etree.SubElement(vulns_xml, 'vuln')
                        vulndata = db.t_vulndata[vuln_rec.f_vulndata_id]
                        new_vuln_xml.set('id', vulndata.f_vulnid)
                        new_vuln_xml.set('title', vulndata.f_title)
                        new_vuln_xml.set('severity', str(vulndata.f_severity))
                        new_vuln_xml.set('pci_sev', str(vulndata.f_pci_sev))
                        new_vuln_xml.set('cvss_score', str(vulndata.f_cvss_score))
                        new_vuln_xml.set('cvss_metric', cvss_metrics(vulndata))
                        description = etree.SubElement(new_vuln_xml, 'description')
                        description.text = etree.CDATA(unicode(MARKMIN(vulndata.f_description).xml(), 'utf-8'))
                        solution = etree.SubElement(new_vuln_xml, 'solution')
                        solution.text = etree.CDATA(unicode(MARKMIN(vulndata.f_solution).xml(), 'utf-8'))

                        # find vulnerability references and add them
                        vuln_refs = db(db.t_vuln_references.f_vulndata_id == vulndata.id).select()
                        if len(vuln_refs) > 0:
                            refs_xml = etree.SubElement(new_vuln_xml, 'references')
                            for ref_rec in vuln_refs:
                                record = db.t_vuln_refs[ref_rec.f_vuln_ref_id]
                                ref_xml = etree.SubElement(refs_xml, 'reference')
                                ref_xml.set('source', record.f_source)
                                ref_xml.text = record.f_text.decode('utf-8')

            # accounts
            accounts = db(db.t_accounts.f_services_id == svc_rec.id).select()
            if len(accounts) > 0:
                accounts_xml = etree.SubElement(service_xml, 'accounts')
                for acct_rec in accounts:
                    acct_xml = etree.SubElement(accounts_xml, 'account')

                    if acct_rec.f_username not in notin:
                        elem = etree.SubElement(acct_xml, 'username')
                        elem.text = acct_rec.f_username.decode('utf-8')

                    if acct_rec.f_fullname not in notin:
                        elem = etree.SubElement(acct_xml, 'fullname')
                        elem.text = acct_rec.f_fullname.decode('utf-8')

                    if acct_rec.f_password not in notin:
                        elem = etree.SubElement(acct_xml, 'password')
                        elem.text = acct_rec.f_password.decode('utf-8')

                    if acct_rec.f_hash1 not in notin:
                        elem = etree.SubElement(acct_xml, 'hash1')
                        elem.text = acct_rec.f_hash1

                    if acct_rec.f_hash1_type not in notin:
                        elem = etree.SubElement(acct_xml, 'hash1_type')
                        elem.text = acct_rec.f_hash1_type

                    if acct_rec.f_hash2 not in notin:
                        elem = etree.SubElement(acct_xml, 'hash2')
                        elem.text = acct_rec.f_hash2

                    if acct_rec.f_hash2_type not in notin:
                        elem = etree.SubElement(acct_xml, 'hash2_type')
                        elem.text = acct_rec.f_hash2_type

                    if acct_rec.f_uid not in notin:
                        elem = etree.SubElement(acct_xml, 'uid')
                        elem.text = acct_rec.f_uid

                    if acct_rec.f_gid not in notin:
                        elem = etree.SubElement(acct_xml, 'gid')
                        elem.text = acct_rec.f_gid

                    if acct_rec.f_level not in notin:
                        elem = etree.SubElement(acct_xml, 'level')
                        elem.text = acct_rec.f_level

                    if acct_rec.f_domain not in notin:
                        elem = etree.SubElement(acct_xml, 'domain')
                        elem.text = acct_rec.f_domain.decode('utf-8')

                    if acct_rec.f_description not in notin:
                        elem = etree.SubElement(acct_xml, 'description')
                        elem.text = acct_rec.f_description.decode('utf-8')

    result = etree.tostring(kvasir_results_xml, pretty_print=True, encoding=unicode)
    return result
예제 #27
0
파일: hosts.py 프로젝트: kimdane/Kvasir
def list():
    response.title = "%s :: Host Listing" % (settings.title)
    # hostfilter is a session variable that can be
    # None -- no host filtering
    # (userid, <x>) - limit on user id
    # (assetgroup, <x>) - limit on asset group
    # (range, <x>) - limit on subnet (eg: 192.168)
    hostfilter = session.hostfilter
    if hostfilter is None:
        # if no filter is set then we blank it out
        if session.hostfilter is None:
            session.hostfilter = [(None, None), False]

    if request.extension == 'json':
        # from datetime import datetime, timedelta
        # host_start = datetime.now()
        tot_vuln = 0
        tot_hosts = 0

        """
        # load all the vulndata from service_vulns into a dictionary
        # so we only have to query the memory variables instead of
        # the database each time. We need to collect:
        # svc_vulndata[f_service_id] = (f_vulnid, f_severity, f_cvss_score)
        svc_vulndata = {}

        rows = s_service_vuln_data.select( db.t_vulndata.id, db.t_vulndata.f_vulnid, db.t_vulndata.f_severity, db.t_vulndata.f_cvss_score, cache=(cache.ram, 60))
        for r in rows:
            #exploitcount = db(db.t_exploit_references.f_vulndata_id == r.id).count()
            svc_vulndata[r.id] = ( r.f_vulnid,
                                   r.f_severity,
                                   r.f_cvss_score,
                                   r.t_exploit_references.count())
        """

        # build the query variable.. first all hosts then check
        # if a hostfilter is applied
        q = (db.t_hosts.id > 0)
        q = create_hostfilter_query(session.hostfilter, q)

        aaData = []
        rows = db(q).select(db.t_hosts.ALL, db.t_host_os_refs.f_certainty, db.t_os.f_title, db.auth_user.username,
                            left=(db.t_host_os_refs.on(db.t_hosts.id==db.t_host_os_refs.f_hosts_id),
                                  db.t_os.on(db.t_os.id==db.t_host_os_refs.f_os_id),
                                  db.auth_user.on(db.t_hosts.f_engineer==db.auth_user.id)),
                            orderby=db.t_hosts.id|~db.t_host_os_refs.f_certainty)
        # datatable formatting is specific, crud results are not
        seen = set()
        for r in rows:
            if r.t_hosts.id not in seen and not seen.add(r.t_hosts.id): # kludge way to select only rows per host with the best OS-guess
                spanflags = []
                if r.t_hosts.f_confirmed:
                    confirmed = 'hosts_select_confirmed'
                    spanflags.append('<span class="badge"><i class="icon-check"></i></span>')
                else:
                    confirmed = 'hosts_select_unconfirmed'

                if r.t_hosts.f_accessed:
                    spanflags.append('<span class="badge badge-success"><i class="icon-heart"></i></span>')
                if r.t_hosts.f_followup:
                    spanflags.append('<span class="badge badge-important"><i class="icon-flag"></i></span>')

                confirmed = '<div class="%s">%s</div>' % (confirmed, " ".join(spanflags))

                if r.t_hosts.f_ipv4:
                    ipv4 = A(r.t_hosts.f_ipv4, _id='ipv4', _href=URL('detail', extension='html', args=[r.t_hosts.id]), _target="host_detail_%s" % (r.t_hosts.id)).xml()
                else:
                    ipv4 = ""
                if r.t_hosts.f_ipv6:
                    ipv6 = A(r.t_hosts.f_ipv6, _id='ipv6', _href=URL('detail', extension='html', args=[r.t_hosts.id]), _target="host_detail_%s" % (r.t_hosts.id)).xml()
                else:
                    ipv6 = ""

                if r.t_os.f_title is None:
                    os = "Unknown"
                else:
                    os = r.t_os.f_title

                atxt = {
                     '0': confirmed,
                     '1': ipv4,
                     '2': ipv6,
                     '3': r.t_hosts.f_service_count,
                     '4': r.t_hosts.f_vuln_count,
                     '5': "<span class=\"severity_sparkline\" values=\"%s\"></span>" % (r.t_hosts.f_vuln_graph),
                     '6': r.t_hosts.f_exploit_count,
                     '7': r.t_hosts.f_hostname,
                     '8': r.t_hosts.f_netbios_name,
                     '9': os,
                     '10': r.auth_user.username,
                     '11': r.t_hosts.f_asset_group,
                     'DT_RowId': "%s" % (r.t_hosts.id),
                }

                aaData.append(atxt)
                #print("Total time in vuln processing: %s seconds" % (tot_vuln))
                #print("Host record processed in %s seconds" % (timedelta.total_seconds(datetime.now() - row_start)))
                tot_hosts += 1

        result = { 'sEcho': request.vars.sEcho,
                   'iTotalRecords': len(aaData),
                   'iTotalDisplayRecords': len(aaData),
                   'aaData': aaData,
                   }

        #print("Host_select processed %s hosts in %s seconds" % (tot_hosts, timedelta.total_seconds(datetime.now() - host_start)))
        return result
    else:
        add_hosts = AddModal(
            db.t_hosts, 'Add Host', 'Add Host', 'Add Host',
            fields = [
                'f_ipv4',
                'f_ipv6',
                'f_hostname',
                'f_netbios_name',
                'f_macaddr',
                'f_engineer',
                'f_asset_group',
            ],
            cmd = 'hosttable.fnReloadAjax();'
        )
        db.t_hosts.id.comment = add_hosts.create()
        response.files.append(URL(request.application,'static','js/jquery.sparkline.js'))
        return dict(hostfilter=session.hostfilter, add_hosts=add_hosts)
예제 #28
0
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)
예제 #29
0
def report():
    """
    Genereate a HTML-report with fields from statistics, hosts, vulns, and summaries from the wiki
    """

    statistics = db_statistics()
    adv_stats = adv_db_statistics()
    graphs = graphs_index()

    customer = settings.customer
    assessment = settings.assessment_typed
    start_date = settings.start_date or 'START DATE'
    end_date = settings.end_date or 'END DATE'

    # grab the filter type and value if provided or from the session
    if session.hostfilter is None:
        f_type = request.vars.f_type or None
        f_value = request.vars.f_value or None
    else:
        f_type = session.hostfilter[0]
        f_value = session.hostfilter[1]

    # this is a little hack to ensure a record is either blank or None
    # use it as "if variable not in notin:"
    notin = [None, '']
    unknown_cpeid_counter = 0

    hosts = []
    vulnerabilities = {}
    # go through each host, adding the os, services and vulns accordingly
    query = create_hostfilter_query([(f_type, f_value), False])
    for host_rec in db(query).select():
        host = {}
        host['ipv4'] = host_rec.f_ipv4
        host['asset_group'] = host_rec.f_asset_group
        if host_rec.f_ipv6:
            host['ipv6'] = host_rec.f_ipv6
        if host_rec.f_macaddr:
            host['macaddr'] = host_rec.f_macaddr
        if host_rec.f_hostname:
            host['hostname'] = host_rec.f_hostname.decode('utf-8')
        if host_rec.f_netbios_name:
            host['netbios_name'] = host_rec.f_netbios_name.decode('utf-8')

        # build the os information using the highest certainty record
        highest = (0, None)
        for os_rec in db(db.t_host_os_refs.f_hosts_id == host_rec.id).select():
            if os_rec.f_certainty > highest[0]:
                highest = (os_rec.f_certainty, os_rec)

        if highest[0] > 0:
            # add os element to the host
            record = highest[1]
            host['os'] = record
            host['os']['certainty'] = str(highest[0])
            if record.f_class not in notin:
                host['os']['class'] = record.f_class
            if record.f_family not in notin:
                host['os']['family'] = record.f_family

            # since some os records may not have a cpe id we'll mask them with
            # using their title, replacing spaces with underscores
            t_os_rec = db.t_os[record.f_os_id]
            if t_os_rec.f_cpename in notin:
                cpeid = t_os_rec.f_title.replace(' ', '_')
            else:
                cpeid = t_os_rec.f_cpename

            host['os']['id'] = cpeid

            # if the id isn't in os_records, add it
            # if 1:
            #     os_rec = db.t_os[highest[1].f_os_id]
            #     host['os']['id'] = cpeid
            #     host['os']['title'] = os_rec.f_title
            #
            #     if os_rec.f_vendor not in notin:
            #         host['os']['vendor'] = os_rec.f_vendor
            #
            #     if os_rec.f_product not in notin:
            #         host['os']['product'] = os_rec.f_product
            #
            #     if os_rec.f_version not in notin:
            #         host['os']['version'] = os_rec.f_version
            #
            #     if os_rec.f_update not in notin:
            #         host['os']['update'] = os_rec.f_update
            #
            #     if os_rec.f_edition not in notin:
            #         host['os']['edition'] = os_rec.f_edition
            #
            #     if os_rec.f_language not in notin:
            #         host['os']['language'] = os_rec.f_language

        # snmp strings
        snmp_recs = db(db.t_snmp.f_hosts_id == host_rec.id).select()
        if len(snmp_recs) > 0:
            host['snmps'] = []
            for record in snmp_recs:
                snmp = {}
                if record.f_community not in notin:
                    snmp['community'] = record.f_community.decode('utf-8')
                    snmp['version'] = record.f_version
                    snmp['access'] = record.f_access
                    host['snmps'].append(snmp)

        # netbios information
        netb_record = db(
            db.t_netbios.f_hosts_id == host_rec.id).select().first() or None
        if netb_record:
            host['netbios'] = {}
            if netb_record.f_type not in notin:
                host['netbios']['type'] = netb_record.f_type
            if netb_record.f_domain not in notin:
                host['netbios']['domain'] = netb_record.f_domain.decode(
                    'utf-8')
            if netb_record.f_lockout_limit not in notin:
                host['netbios']['lockout_limit'] = str(
                    netb_record.f_lockout_limit)
            if netb_record.f_lockout_duration not in notin:
                host['netbios']['lockout_duration'] = str(
                    netb_record.f_lockout_duration)

            if netb_record.f_advertised_names is not None:
                for name in netb_record.f_advertised_names:
                    host['netbios']['advertised_name'] = name.decode('utf-8')

        # build the services and vulnerabilities
        host['services'] = []
        for svc_rec in db(db.t_services.f_hosts_id == host_rec.id).select():
            service = {}
            service['proto'] = svc_rec.f_proto
            service['number'] = int(svc_rec.f_number)

            if svc_rec.f_name not in notin:
                service['name'] = svc_rec.f_name.decode('utf-8')
            else:
                service['name'] = T('unknown')

            if svc_rec.f_banner not in notin:
                service['banner'] = svc_rec.f_banner.decode('utf-8')

            # service configuration records
            svc_info_recs = db(
                db.t_service_info.f_services_id == svc_rec.id).select()
            if len(svc_info_recs) > 0:
                service['configs'] = []
                for info_rec in svc_info_recs:
                    config = {}
                    if info_rec.f_name not in notin:
                        config['name'] = info_rec.f_name
                        if info_rec.f_text not in notin:
                            config['text'] = info_rec.f_text.decode('utf-8')
                    service['configs'].append(config)

            # vulnerabilities
            svc_vuln_recs = db(
                db.t_service_vulns.f_services_id == svc_rec.id).select()
            if len(svc_vuln_recs) > 0:
                service['vulns'] = []
                for vuln_rec in svc_vuln_recs:
                    vuln = {}
                    vuln['status'] = vuln_rec.f_status
                    vuln['proof'] = vuln_rec.f_proof

                    vulndata = db.t_vulndata[vuln_rec.f_vulndata_id]
                    vuln['vulninfo'] = vulndata
                    vuln['id'] = vulndata.f_vulnid
                    vuln['title'] = vulndata.f_title
                    vuln['severity'] = str(vulndata.f_severity)
                    vuln['pci_sev'] = str(vulndata.f_pci_sev)
                    vuln['cvss_score'] = str(vulndata.f_cvss_score)
                    vuln['cvssmetrics'] = cvss_metrics(vulndata)
                    vuln['description'] = vulndata.f_description
                    vuln['solution'] = vulndata.f_solution

                    # find vulnerability references and add them
                    vuln_refs = db(db.t_vuln_references.f_vulndata_id ==
                                   vulndata.id).select()
                    if len(vuln_refs) > 0:
                        vuln['refs'] = []
                        for ref_rec in vuln_refs:
                            ref = {}
                            record = db.t_vuln_refs[ref_rec.f_vuln_ref_id]
                            ref['source'] = record.f_source
                            ref['text'] = record.f_text.decode('utf-8')
                            vuln['refs'].append(ref)

                    # find vulnerability exploits and add them
                    vuln_exploits = ''  #db(db.t_vuln_references.f_vulndata_id == vulndata.id).select()
                    if len(vuln_exploits) > 0:
                        vuln['exploits'] = []
                        for ref_rec in vuln_refs:
                            ref = {}
                            record = db.t_vuln_refs[ref_rec.f_vuln_ref_id]
                            ref['source'] = record.f_source
                            ref['text'] = record.f_text.decode('utf-8')
                            vuln['refs'].append(ref)

                    if (int(vuln['severity']) > 0):
                        service['vulns'].append(vuln)

                        vuln['hosts'] = []
                        vulnhost = {}
                        vulnhost['ipv4'] = host['ipv4']
                        if 'hostname' in host:
                            vulnhost['hostname'] = host['hostname']
                        else:
                            vulnhost['hostname'] = host['ipv4']
                        vulnhost['svcproto'] = service['proto']
                        vulnhost['svcnumber'] = service['number']
                        vulnhost['status'] = vuln_rec.f_status
                        vulnhost['proof'] = vuln_rec.f_proof
                        vulnhost['url'] = ''
                        if svc_rec.f_name not in notin:
                            vulnhost['svcname'] = svc_rec.f_name.decode(
                                'utf-8')
                        else:
                            vulnhost['svcname'] = T('unknown')
                        if svc_rec.f_banner not in notin:
                            vulnhost['svcbanner'] = svc_rec.f_banner.decode(
                                'utf-8')
                        id = str(vuln_rec.f_vulndata_id)
                        if id not in vulnerabilities:
                            vulnerabilities[id] = vuln
                        vulnerabilities[id]['hosts'].append(vulnhost)

                if len(service['vulns']) is 0:
                    del service['vulns']

            host['services'].append(service)
            # accounts
            #accounts = db(db.t_accounts.f_services_id == svc_rec.id).select()
            # if len(accounts) > 0:
            #     host['accounts'] = []
            #
            #     for acct_rec in accounts:
            #         account = {}
            #
            #         if acct_rec.f_username not in notin:
            #             account['username'] = acct_rec.f_username.decode('utf-8')
            #
            #         if acct_rec.f_fullname not in notin:
            #             account['fullname'] = acct_rec.f_fullname.decode('utf-8')
            #
            #         if acct_rec.f_password not in notin:
            #             account['password'] = acct_rec.f_password.decode('utf-8')
            #
            #         if acct_rec.f_hash1 not in notin:
            #             account['hash1'] = acct_rec.f_hash1
            #
            #         if acct_rec.f_hash1_type not in notin:
            #             account['hash1_type'] = acct_rec.f_hash1_type
            #
            #         if acct_rec.f_hash2 not in notin:
            #             account['hash2'] = acct_rec.f_hash2
            #
            #         if acct_rec.f_hash2_type not in notin:
            #             account['hash2_type'] = acct_rec.f_hash2_type
            #
            #         if acct_rec.f_uid not in notin:
            #             account['uid'] = acct_rec.f_uid
            #
            #         if acct_rec.f_gid not in notin:
            #             account['gid'] = acct_rec.f_gid
            #
            #         if acct_rec.f_level not in notin:
            #             account['level'] = acct_rec.f_level
            #
            #         if acct_rec.f_domain not in notin:
            #             account['domain'] = acct_rec.f_domain.decode('utf-8')
            #
            #         if acct_rec.f_description not in notin:
            #             account['description'] = acct_rec.f_description.decode('utf-8')
            #         host['accounts'].append(account)
        hosts.append(host)
    #response.files.append(URL(request.application,'static','js/jquery.sparkline.js'))

    #get JSON from host.list and use mockjax
    ext = request.extension
    request.extension = 'json'
    hostlist = list()  #Not an empty list
    request.extension = ext
    #remove the engineer field from the customers report
    hostlist['aaData'][-1]['10'] = None
    import re
    hostlist = re.sub("href=\"[^>]*>([^<]*)", "href=\"#\\1\">\\1",
                      str(hostlist))
    listjson = hostlist.replace('\"', '\\\"').replace('\'', '\"').replace(
        'L, ', ', ').replace('None', 'null')
    vulnlst = sorted(vulnerabilities,
                     key=lambda x: int(vulnerabilities[x]['severity']),
                     reverse=True)
    return dict(vulnlst=vulnlst,
                vulnerabilities=vulnerabilities,
                statistics=statistics,
                adv_stats=adv_stats,
                graphs=graphs,
                hosts=hosts,
                hostfilter=session.hostfilter,
                listjson=listjson)
예제 #30
0
파일: vulns.py 프로젝트: v0re/Kvasir
def vulninfo_by_vulnid():
    """
    Returns the vulnerablilty details
    """
    if request.args(0) is None:
        redirect(
            URL('default',
                'error',
                vars={'msg': T('No Vulnerability ID sent')}))

    record = db(db.t_vulndata.f_vulnid == request.args(0)).select().first()
    if record is not None:
        # grab vuln references and format the table
        response.title = "%s :: Vulnerability Popup :: %s" % (settings.title,
                                                              record.f_vulnid)
        #cvss_metrics = "AV:%s/AC:%s/Au:%s/C:%s/I:%s/A:%s" % (record.f_cvss_av,
        #                                                     record.f_cvss_ac,
        #                                                     record.f_cvss_au,
        #                                                     record.f_cvss_c,
        #                                                     record.f_cvss_i,
        #                                                     record.f_cvss_a)

        vulninfo = record
        cvssmetrics = cvss_metrics(record)

        refs = LOAD(request.controller,
                    'vuln_refs_by_vulnid',
                    args=[record.id],
                    ajax=True)
        exploits = LOAD(request.controller,
                        'vuln_exploits_by_vulnid',
                        args=[record.id],
                        ajax=True)

        # TODO: Add hosts with vulnerability -- include service info (proto/port) and
        # ability to delete vuln from service

        query = db.t_service_vulns.f_vulndata_id == record.id
        svc_vulns = db(query).select(db.t_service_vulns.f_services_id,
                                     db.t_service_vulns.f_proof,
                                     db.t_service_vulns.f_status,
                                     db.t_service_vulns.id,
                                     distinct=True)

        hosts_tr = []
        query = (db.t_hosts.id > 0)
        query = create_hostfilter_query(session.hostfilter, query,
                                        't_services')
        hosts_dict = db(query).select(db.t_hosts.id,
                                      cache=(cache.ram, 30)).as_dict()
        hostlist = map(lambda x: x['id'], hosts_dict.itervalues())
        for svc_vuln in svc_vulns:
            svc = db.t_services[svc_vuln.f_services_id]
            if svc is None:
                logger.error(
                    "t_servics_vuln #%s does not link to a t_services.id!" %
                    (svc_vuln.id))
                continue

            if svc.f_hosts_id not in hostlist:
                continue

            host_rec = db.t_hosts[svc.f_hosts_id]
            hosts_tr.append(
                TR(TD(
                    SPAN(I(_class="icon-trash"),
                         _name="host_del",
                         _id=svc_vuln.id)),
                   TD(
                       A(IMG(_src=URL(request.application, 'static/images',
                                      'terminal.png'),
                             _width="20",
                             _height="20",
                             _style="float:left"),
                         "  ",
                         _href="#",
                         _onclick="launchterm('%s')" % (host_rec.id)),
                       host_a_maker(host_rec)),
                   TD("%s/%s" % (svc.f_proto, svc.f_number)),
                   TD(MARKMIN(svc_vuln.f_proof)),
                   TD(svc_vuln.f_status),
                   _id=svc_vuln.id))

        if len(hosts_tr) > 0:
            hosts = TABLE(THEAD(
                TR(
                    TH(T('Del'), _width="5%"),
                    TH(T('Host Information')),
                    TH(T('Port')),
                    TH(T('Proof')),
                    TH(T('Status')),
                )),
                          TBODY(hosts_tr),
                          _id="vulntable",
                          _class="datatable",
                          _width="100%")
        else:
            hosts = None
    else:
        response.title = "%s :: Invalid Vulnerability ID"
        return dict(vulninfo={}, refs={}, exploits={}, hosts={})

    # vuln form data
    vuln = crud.read(db.t_vulndata,
                     record)  #returns read-only for for t_vulndata
    vuln.attributes['_id'] = "vuln_record"
    return dict(vuln=vuln,
                vulninfo=vulninfo,
                cvssmetrics=cvssmetrics,
                refs=refs,
                exploits=exploits,
                hosts=hosts)