コード例 #1
0
ファイル: accounts.py プロジェクト: nxbdi/Kvasir
def import_mass_password():
    """
    Process a mass run of medusa/hydra.. result file will have IP addresses, service and info
    """
    if request.extension == "load":
        buttons = []
    else:
        buttons = ["submit"]

    from skaldship.general import check_datadir

    check_datadir(request.folder)

    form = SQLFORM.factory(
        Field(
            "f_filename",
            "upload",
            uploadfolder=os.path.join(request.folder, settings.password_upload_dir),
            label=T("Password file"),
        ),
        Field(
            "f_ftype",
            "string",
            label=T("File Type"),
            default="Medusa",
            requires=IS_IN_SET(("Medusa", "Hydra", "Metasploit Creds CSV")),
        ),
        Field("f_proto", "string", label=T("Protocol"), default="tcp", requires=IS_IN_SET(("tcp", "udp", "info"))),
        Field("f_number", "string", label=T("Port Number"), requires=IS_NOT_EMPTY()),
        Field("f_message", "string", label=T("Message to add")),
        Field("f_add_hosts", "boolean", label=T("Add Hosts"), comment=T("Add missing hosts to the database")),
        buttons=buttons,
        _action=URL("accounts", "import_mass_password"),
        _id="import_mass_password",
    )

    if request.vars.f_filename is not None:
        orig_filename = request.vars.f_filename.filename
    if form.errors:
        response.flash = "Error in form"
        return TABLE(*[TR(k, v) for k, v in form.errors.items()])
    elif form.accepts(request.vars, session):
        filename = os.path.join(request.folder, settings.password_upload_dir, form.vars.f_filename)
        logger.info("Processing password file: %s" % (filename))
        resp_text = process_mass_password(
            pw_file=filename,
            pw_type=request.vars.f_ftype,
            message=request.vars.f_message,
            proto=request.vars.f_proto,
            portnum=request.vars.f_number,
            add_hosts=request.vars.f_add_hosts,
            user_id=auth.user.id,
        )
        response.flash = resp_text

    response.title = "%s :: Import Mass Password File" % (settings.title)
    if request.extension == "json":
        return dict()
    else:
        return dict(form=form)
コード例 #2
0
ファイル: webimaging.py プロジェクト: KvasirSecurity/Kvasir
def do_screenshot(services=None):
    """
    Grab a screenshot of a URL and import it to the evidence db.
    """

    try:
        from pydal.objects import Row
    except ImportError:
        from gluon.dal import Row
    from skaldship.general import check_datadir

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

    if isinstance(services, int):
        services = [services]

    service_rows = []
    if isinstance(services, list):
        for svc in services:
            service_rows.append(db.t_services[svc])

    if isinstance(services, Row):
        service_rows = [services]

    phantomjs = settings.get('phantomjs', 'phantomjs')
    good_count = 0
    invalid_count = 0
    for svc_rec in service_rows:
        if not isinstance(svc_rec, Row):
            invalid_count += 1
            continue

        ipaddr = svc_rec.f_hosts_id.f_ipaddr
        port = "%s%s" % (svc_rec.f_number, svc_rec.f_proto[0])
        check_datadir(current.globalenv['request'].folder)
        folder = os.path.join(current.globalenv['request'].folder, "data/screenshots")
        filename = "%s-%s-webshot.png" % (ipaddr.replace(':', '_'), port)

        if svc_rec.f_name in ['http', 'https', 'HTTP', 'HTTPS']:
            scheme = svc_rec.f_name.lower()
        else:
            scheme = 'http'
        url = "%s://%s:%s/" % (scheme, ipaddr, svc_rec.f_number)

        res = grab_screenshot(url, os.path.join(folder, filename), phantomjs)
        if res[0]:
            query = (db.t_evidence.f_hosts_id == svc_rec.f_hosts_id) & (db.t_evidence.f_filename == filename)
            db.t_evidence.update_or_insert(
                query, f_filename=filename, f_hosts_id=svc_rec.f_hosts_id, f_data=res[1],
                f_evidence=filename, f_type="Screenshot", f_text="Web Screenshot - %s" % (url))
            db.commit()
            print(" [-] Web screenshot obtained: %s" % (url))
            good_count += 1
        else:
            print(" [!] Web screenshot failed: %s" % (url))
            invalid_count += 1

    return [good_count, invalid_count]
コード例 #3
0
ファイル: accounts.py プロジェクト: kimdane/Kvasir
def update_hashes_by_file():
    """
    Upload and parse a list of cracked hashes
    Supporting password file formats:
       JTR PWDUMP
       JTR Shadow
       Hash:Password
       Password:Hash
    """
    import os
    from skaldship.general import check_datadir
    check_datadir(request.folder)

    if request.extension == "load":
        buttons = []
    else:
        buttons = ['submit']

    pw_set = ('JTR PWDUMP', 'JTR Shadow', 'Hash:Password', 'Password:Hash')

    form = SQLFORM.factory(
        Field('f_filename',
              'upload',
              uploadfolder=os.path.join(request.folder,
                                        settings.password_upload_dir),
              label=T('Password file')),
        Field('f_type',
              'string',
              label=T('File type'),
              default='PWDUMP',
              requires=IS_IN_SET(pw_set)),
        Field('f_message', 'string', label=T('Message to add')),
        buttons=buttons,
        _action=URL('accounts', 'update_hashes_by_file'),
        _id='accounts_update_hashes_by_file',
    )

    resp_text = ""
    accounts_added = []
    accounts_updated = []
    if request.vars.f_filename is not None:
        orig_filename = request.vars.f_filename.filename
    if form.errors:
        response.flash = 'Error in form'
        return TABLE(*[TR(k, v) for k, v in form.errors.items()])
    elif form.accepts(request.vars, session):
        filename = os.path.join(request.folder, settings.password_upload_dir,
                                form.vars.f_filename)
        logger.info("Processing password file: %s" % (filename))
        resp_text = process_cracked_file(pw_file=filename,
                                         file_type=request.vars.f_type,
                                         message=request.vars.f_message)

    response.title = "%s :: Update Password Hashes by File" % (settings.title)
    if request.extension == "json":
        return dict()
    else:
        return dict(form=form, resp_text=resp_text)
コード例 #4
0
ファイル: default.py プロジェクト: 001001/Kvasir
def database_restore():
    """
    Retore a database from CSV data
    """
    response.title = "%s :: Database CSV Restore" % (settings.title)
    import os
    import glob
    from skaldship.general import check_datadir

    check_datadir(request.folder)
    backup_dir = os.path.join(request.folder, "data/backups")
    os.chdir(backup_dir)
    csv_files = []
    for ext in ["*.csv", "*.csv.gz"]:
        csv_files.extend(glob.glob(ext))

    form = SQLFORM.factory(
        Field("file", type="string", requires=IS_EMPTY_OR(IS_IN_SET(csv_files)), label=T("Local File")),
        Field("upload", type="upload", uploadfolder=backup_dir, label=T("Upload CSV File")),
        Field("wipe", type="boolean", default=False, label=T("Wipe all existing data")),
    )

    if form.process().accepted:
        if form.vars.wipe:
            db.t_hosts.truncate(mode="CASCADE")
            db.t_services.truncate(mode="CASCADE")
            db.t_os.truncate(mode="CASCADE")
            db.t_host_os_refs.truncate(mode="CASCADE")
            db.t_apps.truncate(mode="CASCADE")
            db.t_services_apps_refs.truncate(mode="CASCADE")
            db.t_service_vulns.truncate(mode="CASCADE")
            db.t_service_info.truncate(mode="CASCADE")
            db.t_accounts.truncate(mode="CASCADE")
            db.t_host_notes.truncate(mode="CASCADE")
            db.t_evidence.truncate(mode="CASCADE")
            db.t_snmp.truncate(mode="CASCADE")
            db.commit()

        if form.vars.file:
            fname = form.vars.file
        elif form.vars.upload:
            fname = form.vars.upload

        if fname.endswith(".gz"):
            import gzip

            fobj = gzip.open(fname, "rb")
        else:
            fobj = open(fname, "rb")

        db.import_from_csv_file(fobj)

    elif form.errors:
        response.flash = "Error in form"

    os.chdir(request.folder)
    return dict(form=form, backup_dir=backup_dir)
コード例 #5
0
def do_screenshot(services=None):
    """
    Grab a screenshot and import it to the evidence db.
    """

    try:
        from pydal.objects import Row
    except ImportError:
        from gluon.dal import Row
    from gluon import current
    import os
    from skaldship.general import check_datadir
    from multiprocessing import Process

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

    if isinstance(services, int):
        services = [services]

    service_rows = []
    if isinstance(services, list):
        for svc in services:
            service_rows.append(db.t_services[svc])

    if isinstance(services, Row):
        service_rows = [services]

    good_count = 0
    invalid_count = 0

    for svc_rec in service_rows:
        if not isinstance(svc_rec, Row):
            invalid_count += 1
            continue

        ipaddr = svc_rec.f_hosts_id.f_ipaddr
        port = svc_rec.f_number
        check_datadir(current.globalenv['request'].folder)
        folder = os.path.join(current.globalenv['request'].folder, "data/screenshots")
        filename = "%s-%st-vnc_screenshot.png" % (ipaddr.replace(':', '_'), port)

        res = grab_screenshot(ipaddr, port, os.path.join(folder, filename))
        if res[0]:
            query = (db.t_evidence.f_hosts_id == svc_rec.f_hosts_id) & (db.t_evidence.f_filename == filename)
            db.t_evidence.update_or_insert(
                query, f_filename=filename, f_hosts_id=svc_rec.f_hosts_id, f_data=res[1],
                f_evidence=filename, f_type="Screenshot", f_text="VNC Screenshot - %s:%s" % (ipaddr, port))
            db.commit()
            print(" [-] VNC screenshot obtained: %s:%s" % (ipaddr, port))
            good_count += 1
        else:
            print(" [!] VNC screenshot failed: %s:%s" % (ipaddr, port))
            invalid_count += 1

    return [good_count, invalid_count]
コード例 #6
0
ファイル: default.py プロジェクト: v0re/Kvasir
def database_restore():
    """
    Retore a database from CSV data
    """
    response.title = "%s :: Database CSV Restore" % (settings.title)
    import os
    import glob
    from skaldship.general import check_datadir

    check_datadir(request.folder)
    backup_dir = os.path.join(request.folder, 'data/backups')
    os.chdir(backup_dir)
    csv_files = []
    for ext in ["*.csv", "*.csv.gz"]:
        csv_files.extend(glob.glob(ext))

    form = SQLFORM.factory(
        Field('file', type='string', requires=IS_EMPTY_OR(IS_IN_SET(csv_files)), label=T('Local File')),
        Field('upload', type='upload', uploadfolder=backup_dir, label=T('Upload CSV File')),
        Field('wipe', type='boolean', default=False, label=T('Wipe all existing data'))
    )

    if form.process().accepted:
        if form.vars.wipe:
            db.t_hosts.truncate(mode="CASCADE")
            db.t_services.truncate(mode="CASCADE")
            db.t_os.truncate(mode="CASCADE")
            db.t_host_os_refs.truncate(mode="CASCADE")
            db.t_apps.truncate(mode="CASCADE")
            db.t_services_apps_refs.truncate(mode="CASCADE")
            db.t_service_vulns.truncate(mode="CASCADE")
            db.t_service_info.truncate(mode="CASCADE")
            db.t_accounts.truncate(mode="CASCADE")
            db.t_host_notes.truncate(mode="CASCADE")
            db.t_evidence.truncate(mode="CASCADE")
            db.t_snmp.truncate(mode="CASCADE")
            db.commit()

        if form.vars.file:
            fname = form.vars.file
        elif form.vars.upload:
            fname = form.vars.upload

        if fname.endswith('.gz'):
            import gzip
            fobj = gzip.open(fname, 'rb')
        else:
            fobj = open(fname, 'rb')

        db.import_from_csv_file(fobj)

    elif form.errors:
        response.flash = "Error in form"

    os.chdir(request.folder)
    return dict(form=form, backup_dir=backup_dir)
コード例 #7
0
ファイル: hping.py プロジェクト: v0re/Kvasir
def import_scan():
    """
    Upload/import hping Scan file via scheduler task
    """
    import time
    from skaldship.general import check_datadir

    filedir = os.path.join(request.folder, 'data', 'scanfiles')
    check_datadir(request.folder)
    response.title = "%s :: Import hping Scan Results" % (settings.title)

    fields = []

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

    fields.append(
        Field('f_filename',
              'upload',
              uploadfolder=filedir,
              label=T('hping File')))
    fields.append(
        Field('f_engineer',
              type='integer',
              label=T('Engineer'),
              default=auth.user.id,
              requires=IS_IN_SET(userlist)))
    fields.append(
        Field('f_asset_group',
              type='string',
              label=T('Asset Group'),
              requires=IS_NOT_EMPTY()))
    form = SQLFORM.factory(*fields, table_name='hping')

    if form.errors:
        response.flash = 'Error in form'
    elif form.accepts(request.vars, session):
        # process a hping file
        filename = form.vars.f_filename
        filename = os.path.join(filedir, form.vars.f_filename)

        from skaldship.hping import process_file
        print("Starting hping Import")
        process_file(
            filename=filename,
            asset_group=form.vars.f_asset_group,
            engineer=form.vars.f_engineer,
        )
        response.flash = "hping upload complete"
        redirect(URL('default', 'index'))

    return dict(form=form)
コード例 #8
0
ファイル: accounts.py プロジェクト: kimdane/Kvasir
def update_hashes_by_file():
    """
    Upload and parse a list of cracked hashes
    Supporting password file formats:
       JTR PWDUMP
       JTR Shadow
       Hash:Password
       Password:Hash
    """
    import os
    from skaldship.general import check_datadir

    check_datadir(request.folder)

    if request.extension == "load":
        buttons = []
    else:
        buttons = ["submit"]

    pw_set = ("JTR PWDUMP", "JTR Shadow", "Hash:Password", "Password:Hash")

    form = SQLFORM.factory(
        Field(
            "f_filename",
            "upload",
            uploadfolder=os.path.join(request.folder, settings.password_upload_dir),
            label=T("Password file"),
        ),
        Field("f_type", "string", label=T("File type"), default="PWDUMP", requires=IS_IN_SET(pw_set)),
        Field("f_message", "string", label=T("Message to add")),
        buttons=buttons,
        _action=URL("accounts", "update_hashes_by_file"),
        _id="accounts_update_hashes_by_file",
    )

    resp_text = ""
    accounts_added = []
    accounts_updated = []
    if request.vars.f_filename is not None:
        orig_filename = request.vars.f_filename.filename
    if form.errors:
        response.flash = "Error in form"
        return TABLE(*[TR(k, v) for k, v in form.errors.items()])
    elif form.accepts(request.vars, session):
        filename = os.path.join(request.folder, settings.password_upload_dir, form.vars.f_filename)
        logger.info("Processing password file: %s" % (filename))
        resp_text = process_cracked_file(
            pw_file=filename, file_type=request.vars.f_type, message=request.vars.f_message
        )

    response.title = "%s :: Update Password Hashes by File" % (settings.title)
    if request.extension == "json":
        return dict()
    else:
        return dict(form=form, resp_text=resp_text)
コード例 #9
0
def do_screenshot(services=None):
    """
    Grab a screenshot and import it to the evidence db.
    """

    from gluon.dal import Row
    from gluon import current
    import os
    from skaldship.general import check_datadir
    from multiprocessing import Process

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

    if isinstance(services, int):
        services = [services]

    service_rows = []
    if isinstance(services, list):
        for svc in services:
            service_rows.append(db.t_services[svc])

    if isinstance(services, Row):
        service_rows = [services]

    good_count = 0
    invalid_count = 0

    for svc_rec in service_rows:
        if not isinstance(svc_rec, Row):
            invalid_count += 1
            continue

        # go with ipv6 if defined, else pick the ipv4 address
        ipaddr = svc_rec.f_hosts_id.f_ipv6 or svc_rec.f_hosts_id.f_ipv4
        port = svc_rec.f_number
        check_datadir(current.globalenv['request'].folder)
        folder = os.path.join(current.globalenv['request'].folder, "data/screenshots")
        filename = "%s-%st-vnc_screenshot.png" % (ipaddr.replace(':', '_'), port)

        res = grab_screenshot(ipaddr, port, os.path.join(folder, filename))
        if res[0]:
            query = (db.t_evidence.f_hosts_id == svc_rec.f_hosts_id) & (db.t_evidence.f_filename == filename)
            db.t_evidence.update_or_insert(
                query, f_filename=filename, f_hosts_id=svc_rec.f_hosts_id, f_data=res[1],
                f_evidence=filename, f_type="Screenshot", f_text="VNC Screenshot - %s:%s" % (ipaddr, port))
            db.commit()
            print(" [-] VNC screenshot obtained: %s:%s" % (ipaddr, port))
            good_count += 1
        else:
            print(" [!] VNC screenshot failed: %s:%s" % (ipaddr, port))
            invalid_count += 1

    return [good_count, invalid_count]
コード例 #10
0
ファイル: default.py プロジェクト: 001001/Kvasir
def database_backup():
    """
    Export/backup database in CSV format
    """
    response.title = "%s :: Database CSV Backup" % (settings.title)
    import os
    import gzip
    from datetime import datetime

    backup_dir = os.path.join(request.folder, "data/backups")
    form = SQLFORM.factory(
        Field("download", type="boolean", default=True, label=T("Download")),
        Field("gzip", type="boolean", default=True, label=T("GZip Compress")),
    )

    if form.process().accepted:
        fname = "kvasir-%s-%s-%s" % (
            settings.customer,
            settings.assesment_type,
            datetime.now().strftime("%m%d%y-%H%M%S"),
        )
        fname = "".join([x if x.isalnum() else "_" for x in fname])
        if form.vars.download:
            # generate csv and download
            s = StringIO.StringIO()
            db.export_to_csv_file(s)
            response.headers["Content-Type"] = "text/csv"
            if form.vars.gzip:
                gz_s = StringIO.StringIO()
                response.headers["Content-Disposition"] = 'attachment; filename="%s.gz"' % fname
                gz = gzip.GzipFile(filename="temp.gz", mode="wb", fileobj=gz_s)
                gz.write(s.getvalue())
                gz.close()
                return gz_s.getvalue()
            else:
                response.headers["Content-Disposition"] = 'attachment; filename="%s"' % fname
                return s.getvalue()
        else:
            # generate csv and store locally
            from skaldship.general import check_datadir

            check_datadir(request.folder)
            tmpfile = os.path.join(request.folder, "data/backups", fname)
            if form.vars.gzip:
                fobj = gzip.open(tmpfile + ".gz", "wb")
            else:
                fobj = open(tmpfile, "wb")
            db.export_to_csv_file(fobj)
            return redirect(URL("default", "data_dir/backups"))
    elif form.errors:
        response.flash = "Error in form"

    return dict(form=form, backup_dir=backup_dir)
コード例 #11
0
ファイル: accounts.py プロジェクト: KvasirSecurity/Kvasir
def import_mass_password():
    """
    Process a mass run of medusa/hydra.. result file will have IP addresses, service and info
    """
    if request.extension == "load":
        buttons=[]
    else:
        buttons=['submit']

    from skaldship.general import check_datadir
    check_datadir(request.folder)

    form=SQLFORM.factory(
        Field('f_filename', 'upload', uploadfolder=os.path.join(request.folder, settings.password_upload_dir),
              label=T('Password file'), requires=IS_NOT_EMPTY(error_message=T('Filename required'))),
        Field('f_ftype', 'string', label=T('File Type'), default="Medusa",
              requires=IS_IN_SET(('Medusa', 'Hydra', 'Metasploit Creds CSV'))),
        Field('f_proto', 'string', label=T('Protocol'), default='tcp', requires=IS_IN_SET(('tcp', 'udp', 'info'))),
        Field('f_number', 'integer', label=T('Port Number'), requires=IS_INT_IN_RANGE(0, 65536)),
        Field('f_message', 'string', label=T('Message to add')),
        Field('f_add_hosts', 'boolean', label=T('Add Hosts'), comment=T('Add missing hosts to the database')),
        buttons=buttons, _action=URL('accounts', 'import_mass_password'), _id='import_mass_password',
    )

    if form.errors:
        response.flash = 'Error in form'
        return TABLE(*[TR(k, v) for k, v in form.errors.items()])
    elif form.accepts(request.vars, session):
        if request.vars.f_filename is not None:
            orig_filename = request.vars.f_filename.filename
        filename = os.path.join(request.folder, settings.password_upload_dir, form.vars.f_filename)
        logger.info("Processing password file: %s" % (filename))
        resp_text = process_mass_password(
            pw_file=filename,
            pw_type=request.vars.f_ftype,
            message=request.vars.f_message,
            proto=request.vars.f_proto,
            portnum=request.vars.f_number,
            add_hosts=request.vars.f_add_hosts,
            user_id=auth.user.id,
        )
        response.flash = resp_text

    response.title = "%s :: Import Mass Password File" % (settings.title)
    if request.extension == "json":
        return dict()
    else:
        return dict(form=form)
コード例 #12
0
ファイル: accounts.py プロジェクト: v0re/Kvasir
def import_mass_password():
    """
    Process a mass run of medusa/hydra.. result file will have IP addresses, service and info
    """
    if request.extension == "load":
        buttons=[]
    else:
        buttons=['submit']

    from skaldship.general import check_datadir
    check_datadir(request.folder)

    form=SQLFORM.factory(
        Field('f_filename', 'upload', uploadfolder=os.path.join(request.folder, settings.password_upload_dir),
              label=T('Password file'), requires=IS_NOT_EMPTY(error_message=T('Filename required'))),
        Field('f_ftype', 'string', label=T('File Type'), default="Medusa",
              requires=IS_IN_SET(('Medusa', 'Hydra', 'Metasploit Creds CSV'))),
        Field('f_proto', 'string', label=T('Protocol'), default='tcp', requires=IS_IN_SET(('tcp', 'udp', 'info'))),
        Field('f_number', 'integer', label=T('Port Number'), requires=IS_INT_IN_RANGE(0, 65536)),
        Field('f_message', 'string', label=T('Message to add')),
        Field('f_add_hosts', 'boolean', label=T('Add Hosts'), comment=T('Add missing hosts to the database')),
        buttons=buttons, _action=URL('accounts', 'import_mass_password'), _id='import_mass_password',
    )

    if form.errors:
        response.flash = 'Error in form'
        return TABLE(*[TR(k, v) for k, v in form.errors.items()])
    elif form.accepts(request.vars, session):
        if request.vars.f_filename is not None:
            orig_filename = request.vars.f_filename.filename
        filename = os.path.join(request.folder, settings.password_upload_dir, form.vars.f_filename)
        logger.info("Processing password file: %s" % (filename))
        resp_text = process_mass_password(
            pw_file=filename,
            pw_type=request.vars.f_ftype,
            message=request.vars.f_message,
            proto=request.vars.f_proto,
            portnum=request.vars.f_number,
            add_hosts=request.vars.f_add_hosts,
            user_id=auth.user.id,
        )
        response.flash = resp_text

    response.title = "%s :: Import Mass Password File" % (settings.title)
    if request.extension == "json":
        return dict()
    else:
        return dict(form=form)
コード例 #13
0
ファイル: hping.py プロジェクト: KvasirSecurity/Kvasir
def import_scan():
    """
    Upload/import hping Scan file via scheduler task
    """
    import time
    from skaldship.general import check_datadir

    filedir = os.path.join(request.folder,'data','scanfiles')
    check_datadir(request.folder)
    response.title = "%s :: Import hping Scan Results" % (settings.title)

    fields = []

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

    fields.append(Field('f_filename', 'upload', uploadfolder=filedir, label=T('hping File')))
    fields.append(Field('f_engineer', type='integer', label=T('Engineer'), default=auth.user.id, requires=IS_IN_SET(userlist)))
    fields.append(Field('f_asset_group', type='string', label=T('Asset Group'), requires=IS_NOT_EMPTY()))
    form = SQLFORM.factory(*fields, table_name='hping')

    if form.errors:
        response.flash = 'Error in form'
    elif form.accepts(request.vars, session):
        # process a hping file
        filename = form.vars.f_filename
        filename = os.path.join(filedir, form.vars.f_filename)

        from skaldship.hping import process_file
        print("Starting hping Import")
        process_file(
            filename=filename,
            asset_group=form.vars.f_asset_group,
            engineer=form.vars.f_engineer,
        )
        response.flash = "hping upload complete"
        redirect(URL('default', 'index'))

    return dict(form=form)
コード例 #14
0
ファイル: accounts.py プロジェクト: KvasirSecurity/Kvasir
def update_hashes_by_file():
    """
    Upload and parse a list of cracked hashes
    Supporting password file formats:
       JTR PWDUMP
       JTR Shadow
       Hash:Password
       Password:Hash
    """
    import os
    from skaldship.general import check_datadir
    check_datadir(request.folder)

    if request.extension == "load":
        buttons=[]
    else:
        buttons=['submit']

    pw_set = ('JTR PWDUMP', 'JTR Shadow', 'Hash:Password', 'Password:Hash')

    form = SQLFORM.factory(
        Field('f_filename', 'upload', uploadfolder=os.path.join(request.folder, settings.password_upload_dir), label=T('Password file')),
        Field('f_type', 'string', label=T('File type'), default='PWDUMP', requires=IS_IN_SET(pw_set)),
        Field('f_message', 'string', label=T('Message to add')),
        buttons=buttons, _action=URL('accounts', 'update_hashes_by_file'), _id='accounts_update_hashes_by_file',
    )

    if form.errors:
        response.flash = 'Error in form'
        return TABLE(*[TR(k, v) for k, v in form.errors.items()])
    elif form.accepts(request.vars, session):
        filename = os.path.join(request.folder, settings.password_upload_dir, form.vars.f_filename)
        logger.info("Processing password file: %s" % (filename))
        response.flash = process_cracked_file(
            pw_file=filename, file_type=request.vars.f_type, message=request.vars.f_message
        )

    response.title = "%s :: Update Password Hashes by File" % (settings.title)
    return dict(form=form)
コード例 #15
0
def import_xml_scan():
    """
    Upload/import Nmap XML Scan file via scheduler task
    """
    import time
    from skaldship.general import check_datadir
    from skaldship.metasploit import msf_get_config
    msf_settings = msf_get_config(session)

    try:
        # check to see if we have a Metasploit RPC instance configured and talking
        from MetasploitProAPI import MetasploitProAPI
        msf_api = MetasploitProAPI(host=msf_settings['url'],
                                   apikey=msf_settings['key'])
        working_msf_api = msf_api.login()
    except:
        working_msf_api = False

    filedir = os.path.join(request.folder, 'data', 'scanfiles')
    check_datadir(request.folder)
    response.title = "%s :: Import Nmap XML Scan Results" % (settings.title)

    fields = []

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

    fields.append(
        Field('f_filename',
              'upload',
              uploadfolder=filedir,
              label=T('Nmap XML File')))
    fields.append(
        Field('f_engineer',
              type='integer',
              label=T('Engineer'),
              default=auth.user.id,
              requires=IS_IN_SET(userlist)))
    fields.append(
        Field('f_asset_group',
              type='string',
              label=T('Asset Group'),
              requires=IS_NOT_EMPTY()))

    # If Metasploit available, pull a list of the workspaces and present them
    if working_msf_api:
        msf_workspaces = []
        msf_workspaces.append("None")
        for w in list(msf_api.pro_workspaces().keys()):
            msf_workspaces.append(w)
        fields.append(
            Field('f_msf_workspace',
                  type='string',
                  label=T('MSF Pro Workspace'),
                  requires=IS_EMPTY_OR(IS_IN_SET(msf_workspaces, zero=None))))

    fields.append(
        Field('f_addnoports',
              type='boolean',
              label=T('Add Hosts w/o Ports'),
              default=False))
    fields.append(
        Field('f_include_list', type='text', label=T('Hosts to Only Include')))
    fields.append(
        Field('f_ignore_list', type='text', label=T('Hosts to Ignore')))
    fields.append(
        Field('f_update_hosts',
              type='boolean',
              label=T('Update Host Information'),
              default=False))
    fields.append(
        Field('f_taskit',
              type='boolean',
              default=auth.user.f_scheduler_tasks,
              label=T('Run in background task')))
    form = SQLFORM.factory(*fields, table_name='nmap_xml')

    if form.errors:
        response.flash = 'Error in form'
    elif form.accepts(request.vars, session):
        # process a nmap file
        filename = os.path.join(filedir, form.vars.f_filename)

        # build the hosts only/exclude list
        ip_exclude = []
        data = form.vars.get('f_ignore_list')
        if data:
            ip_exclude = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals
        ip_include = []
        data = form.vars.get('f_include_list')
        if data:
            ip_include = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals

        if form.vars.f_msf_workspace:
            msf_workspace = form.vars.f_msf_workspace
            if msf_workspace == "None":
                msf_workspace = None
        else:
            msf_workspace = None
        msf_settings = {
            'workspace': msf_workspace,
            'url': msf_settings['url'],
            'key': msf_settings['key']
        }

        if form.vars.f_taskit:
            task = scheduler.queue_task(
                scanner_import,
                pvars=dict(
                    scanner='nmap',
                    filename=filename,
                    addnoports=form.vars.f_addnoports,
                    asset_group=form.vars.f_asset_group,
                    engineer=form.vars.f_engineer,
                    msf_settings=msf_settings,
                    ip_ignore_list=ip_exclude,
                    ip_include_list=ip_include,
                    update_hosts=form.vars.f_update_hosts,
                ),
                group_name=settings.scheduler_group_name,
                sync_output=5,
                timeout=settings.scheduler_timeout)
            if task.id:
                redirect(URL('tasks', 'status', args=task.id))
            else:
                response.flash = "Error submitting job: %s" % (task.errors)
        else:
            from skaldship.nmap import process_xml
            print("Starting Nmap XML Import")
            process_xml(
                filename=filename,
                addnoports=form.vars.f_addnoports,
                asset_group=form.vars.f_asset_group,
                engineer=form.vars.f_engineer,
                msf_settings=msf_settings,
                ip_ignore_list=ip_exclude,
                ip_include_list=ip_include,
                update_hosts=form.vars.f_update_hosts,
            )
            response.flash = "Nmap XML upload complete"
            redirect(URL('default', 'index'))

    return dict(form=form)
コード例 #16
0
ファイル: nexpose.py プロジェクト: nullbind/Kvasir
        response.flash = "Error in form"
    elif form.accepts(request.vars, session):
        # process a nexpose file
        if not nxsitelist:
            nexpose_site = "0"
        else:
            nexpose_site = form.vars.f_nexpose_site

        if nexpose_site != "0":
            report = Report()
            report.host = nexpose_config["host"]
            report.port = nexpose_config["port"]
            nx_loggedin = report.login(user_id=nexpose_config["user"], password=nexpose_config["password"])
            if nx_loggedin:
                # have nexpose generate the adhoc report
                check_datadir(request.folder)
                filename = os.path.join(filedir, "%s-%s.xml" % (form.vars.f_asset_group, int(time.time())))
                fout = open(filename, "w")
                fout.write(report.adhoc_generate(filterid=nexpose_site))
                fout.close()
            else:
                response.flash = "Unable to login to Nexpose"
                return dict(form=form)
        else:
            filename = form.vars.f_filename
            filename = os.path.join(filedir, form.vars.f_filename)

        # build the hosts only/exclude list
        ip_exclude = []
        data = form.vars.get("f_ignore_list")
        if data:
コード例 #17
0
ファイル: accounts.py プロジェクト: KvasirSecurity/Kvasir
def import_file():
    """
    Import and parse password file into t_accounts
    """
    import os
    from skaldship.general import check_datadir
    check_datadir(request.folder)

    # Service_id is primary, host_id is secondary, if none then list
    # all the services
    svc_set = []
    url=URL('accounts', 'import_file')
    if request.vars.has_key('service_id'):
        try:
            record = db.t_services[request.vars.service_id]
            svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number)))
            url = URL('accounts', 'import_file', vars={'service_id':request.vars.service_id})
        except:
            pass
    elif request.vars.has_key('host_id'):
        try:
            host_record = get_host_record(request.vars.host_id)
            svc_records = db(db.t_services.f_hosts_id == host_record.id).select(cache=(cache.ram, 30))
            url = URL('accounts', 'import_file', vars={'host_id':request.vars.host_id})
            for record in svc_records:
                svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number)))
        except:
            pass

    if len(svc_set) == 0:
        # all services
        svc_records = db(db.t_services).select(cache=(cache.ram,30))
        svc_set = []
        for record in svc_records:
            svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number)))

    if request.extension == "load":
        buttons=[]
    else:
        buttons=['submit']

    form = SQLFORM.factory(
        Field('f_service', 'string', label=T('Host / Service'), requires=IS_IN_SET(svc_set), default=svc_set[0][0]),
        Field('f_filename', 'upload', uploadfolder=os.path.join(request.folder, settings.password_upload_dir), label=T('Password file')),
        Field('f_type', 'string', label=T('File type'), default='PWDUMP', requires=IS_IN_SET(settings.password_file_types)),
        Field('f_source', 'string', label=T('Source (if necessary)')),
        Field('f_add_to_evidence', 'boolean', label=T('Add Evidence')),
        Field('f_taskit', type='boolean', default=True, label=T('Run in background task')),
        buttons=buttons, _action=url, _id='accounts_import_form'
    )

    resp_text = ""
    accounts_added = []
    accounts_updated = []
    if form.errors:
        response.flash = 'Error in form'
        return TABLE(*[TR(k, v) for k, v in form.errors.items()])
    elif form.accepts(request.vars, session):
        if form.vars.f_filename is not None:
            orig_filename = request.vars.f_filename.filename
        filename = os.path.join(request.folder, settings.password_upload_dir, form.vars.f_filename)
        if form.vars.f_taskit:
            task = scheduler.queue_task(
                accounts_import_file,
                pvars=dict(
                    filename=filename,
                    service=form.vars.f_service,
                    f_type=form.vars.f_type,
                    f_source=form.vars.f_source
                ),
                group_name=settings.scheduler_group_name,
                sync_output=5,
                timeout=settings.scheduler_timeout
            )
            if task.id:
                resp_text = "Submitted file for processing: %s" % (A("task " + str(task.id), _href=URL(c='tasks', f='status', args=task.id)).xml())
            else:
                resp_text = "Error submitting job: %s" % (task.errors)
        else:
            logger.info("Processing password file: %s" % (filename))
            account_data = process_password_file(
                pw_file=filename,
                file_type=request.vars.f_type,
                source=request.vars.f_source
            )
            resp_text = insert_or_update_acct(form.vars.f_service, account_data)
            logger.info(resp_text)

        if form.vars.f_add_to_evidence is True:
            # add the password file to evidence
            try:
                pwdata = open(filename, "r").readlines()
            except Exception, e:
                logger.error("Error opening %s: %s" % (filename, e))

            db.t_evidence.insert( f_hosts_id = db.t_services[form.vars.f_service].f_hosts_id,
                                  f_type = 'Password File',
                                  f_text = form.vars.f_type,
                                  f_filename = orig_filename,
                                  f_evidence = form.vars.f_filename,
                                  f_data = pwdata)
            db.commit()
コード例 #18
0
def paste():
    """
    Import and parse password pasted to a textbox into t_accounts
    """
    from skaldship.general import check_datadir
    check_datadir(request.folder)

    # Service_id is primary, host_id is secondary, if none then list
    # all the services
    svc_set = []
    url = URL('accounts', 'paste')
    if request.vars.has_key('service_id'):
        try:
            record = db.t_services[request.vars.service_id]
            svc_set.append((record.id, "%s :: %s/%s" %
                            (host_title_maker(db.t_hosts[record.f_hosts_id]),
                             record.f_proto, record.f_number)))
            url = URL('accounts',
                      'paste',
                      vars={'service_id': request.vars.service_id})
        except:
            pass
    elif request.vars.has_key('host_id'):
        try:
            host_record = get_host_record(request.vars.host_id)
            svc_records = db(
                db.t_services.f_hosts_id == host_record.id).select(
                    cache=(cache.ram, 30))
            url = URL('accounts',
                      'paste',
                      vars={'host_id': request.vars.host_id})
            for record in svc_records:
                svc_set.append(
                    (record.id, "%s :: %s/%s" %
                     (host_title_maker(db.t_hosts[record.f_hosts_id]),
                      record.f_proto, record.f_number)))
        except:
            pass

    if len(svc_set) == 0:
        # all services
        svc_records = db(db.t_services).select(cache=(cache.ram, 30))
        svc_set = []
        for record in svc_records:
            svc_set.append((record.id, "%s :: %s/%s" %
                            (host_title_maker(db.t_hosts[record.f_hosts_id]),
                             record.f_proto, record.f_number)))

    if request.extension == "load":
        buttons = []
    else:
        buttons = ['submit']

    form = SQLFORM.factory(
        Field('f_service',
              'string',
              label=T('Host / Service'),
              requires=IS_IN_SET(svc_set),
              default=svc_set[0][0]),
        Field('f_pwtext', 'text', label=T('Password text')),
        Field('f_type',
              'string',
              label=T('File type'),
              default='PWDUMP',
              requires=IS_IN_SET(settings.password_file_types)),
        Field('f_source', 'string', label=T('Source (if necessary)')),
        Field('f_add_to_evidence', 'boolean', label=T('Add file to Evidence')),
        buttons=buttons,
        _action=url,
        _id='accounts_paste_form'
        #_action=url, _id='accounts_paste_form', formstyle='bootstrap_modal'
    )

    resp_text = ""
    accounts_added = []
    accounts_updated = []
    if form.errors:
        response.flash = 'Error in form'
        return TABLE(*[TR(k, v) for k, v in form.errors.items()])
    elif form.accepts(request.vars, session):
        from gluon.utils import web2py_uuid
        host_id = db.t_services[form.vars.f_service].f_hosts_id
        pwd_file_dir = os.path.join(request.folder, 'data', 'passwords',
                                    'other')
        if not os.path.exists(pwd_file_dir):
            from gluon.fileutils import mktree
            mktree(pwd_file_dir)
        filename = "%s-pwfile-%s" % (host_id, web2py_uuid())
        full_file_path = os.path.join(request.folder, 'data/passwords/other',
                                      filename)
        of = open(full_file_path, "w")
        of.write(form.vars.f_pwtext)
        of.close()

        logger.debug("Processing password file: %s" % (full_file_path))
        account_data = process_password_file(pw_file=full_file_path,
                                             file_type=request.vars.f_type,
                                             source=request.vars.f_source)
        response.headers[
            'web2py-component-command'] = 'accounttable.fnReloadAjax();'
        resp_text = insert_or_update_acct(form.vars.f_service, account_data)

        if form.vars.f_add_to_evidence is True:
            # add the password file to evidence
            try:
                pwdata = open(full_file_path, "r").readlines()
            except Exception, e:
                logger.error("Error opening %s: %s" % (full_file_path, e))
                resp_text += "Error opening %s: %s\n" % (full_file_path, e)

            db.t_evidence.insert(f_hosts_id=host_id,
                                 f_type='Password File',
                                 f_text=form.vars.f_type,
                                 f_filename=filename,
                                 f_evidence=filename,
                                 f_data=pwdata)
            resp_text += "\n%s added to evidence\n" % (filename)
            db.commit()
コード例 #19
0
def import_file():
    """
    Import and parse password file into t_accounts
    """
    import os
    from skaldship.general import check_datadir
    check_datadir(request.folder)

    # Service_id is primary, host_id is secondary, if none then list
    # all the services
    svc_set = []
    url = URL('accounts', 'import_file')
    if request.vars.has_key('service_id'):
        try:
            record = db.t_services[request.vars.service_id]
            svc_set.append((record.id, "%s :: %s/%s" %
                            (host_title_maker(db.t_hosts[record.f_hosts_id]),
                             record.f_proto, record.f_number)))
            url = URL('accounts',
                      'import_file',
                      vars={'service_id': request.vars.service_id})
        except:
            pass
    elif request.vars.has_key('host_id'):
        try:
            host_record = get_host_record(request.vars.host_id)
            svc_records = db(
                db.t_services.f_hosts_id == host_record.id).select(
                    cache=(cache.ram, 30))
            url = URL('accounts',
                      'import_file',
                      vars={'host_id': request.vars.host_id})
            for record in svc_records:
                svc_set.append(
                    (record.id, "%s :: %s/%s" %
                     (host_title_maker(db.t_hosts[record.f_hosts_id]),
                      record.f_proto, record.f_number)))
        except:
            pass

    if len(svc_set) == 0:
        # all services
        svc_records = db(db.t_services).select(cache=(cache.ram, 30))
        svc_set = []
        for record in svc_records:
            svc_set.append((record.id, "%s :: %s/%s" %
                            (host_title_maker(db.t_hosts[record.f_hosts_id]),
                             record.f_proto, record.f_number)))

    if request.extension == "load":
        buttons = []
    else:
        buttons = ['submit']

    form = SQLFORM.factory(
        Field('f_service',
              'string',
              label=T('Host / Service'),
              requires=IS_IN_SET(svc_set),
              default=svc_set[0][0]),
        Field('f_filename',
              'upload',
              uploadfolder=os.path.join(request.folder,
                                        settings.password_upload_dir),
              label=T('Password file')),
        Field('f_type',
              'string',
              label=T('File type'),
              default='PWDUMP',
              requires=IS_IN_SET(settings.password_file_types)),
        Field('f_source', 'string', label=T('Source (if necessary)')),
        Field('f_add_to_evidence', 'boolean', label=T('Add Evidence')),
        Field('f_taskit',
              type='boolean',
              default=True,
              label=T('Run in background task')),
        buttons=buttons,
        _action=url,
        _id='accounts_import_form')

    resp_text = ""
    accounts_added = []
    accounts_updated = []
    if form.errors:
        response.flash = 'Error in form'
        return TABLE(*[TR(k, v) for k, v in form.errors.items()])
    elif form.accepts(request.vars, session):
        if form.vars.f_filename is not None:
            orig_filename = request.vars.f_filename.filename
        filename = os.path.join(request.folder, settings.password_upload_dir,
                                form.vars.f_filename)
        if form.vars.f_taskit:
            task = scheduler.queue_task(
                accounts_import_file,
                pvars=dict(filename=filename,
                           service=form.vars.f_service,
                           f_type=form.vars.f_type,
                           f_source=form.vars.f_source),
                group_name=settings.scheduler_group_name,
                sync_output=5,
                timeout=settings.scheduler_timeout)
            if task.id:
                resp_text = "Submitted file for processing: %s" % (A(
                    "task " + str(task.id),
                    _href=URL(c='tasks', f='status', args=task.id)).xml())
            else:
                resp_text = "Error submitting job: %s" % (task.errors)
        else:
            logger.info("Processing password file: %s" % (filename))
            account_data = process_password_file(pw_file=filename,
                                                 file_type=request.vars.f_type,
                                                 source=request.vars.f_source)
            resp_text = insert_or_update_acct(form.vars.f_service,
                                              account_data)
            logger.info(resp_text)

        if form.vars.f_add_to_evidence is True:
            # add the password file to evidence
            try:
                pwdata = open(filename, "r").readlines()
            except Exception, e:
                logger.error("Error opening %s: %s" % (filename, e))

            db.t_evidence.insert(
                f_hosts_id=db.t_services[form.vars.f_service].f_hosts_id,
                f_type='Password File',
                f_text=form.vars.f_type,
                f_filename=orig_filename,
                f_evidence=form.vars.f_filename,
                f_data=pwdata)
            db.commit()
コード例 #20
0
ファイル: metasploit.py プロジェクト: Python3pkg/Kvasir
def import_report_xml():
    """
    Upload/import Metasploit XML export file
    """
    import time
    import os
    from skaldship.general import check_datadir

    msf_settings = msf_get_config(session)
    response.title = "%s :: Import Metasploit Pro Report XML" % (
        settings.title)
    filedir = os.path.join(request.folder, 'data', 'scanfiles')
    fields = []
    alert = False
    error = None

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

    fields.append(
        Field('f_filename',
              'upload',
              uploadfolder=filedir,
              label=T('Metasploit XML File')))

    # check to see if we have a Metasploit Pro instance configured and talking
    # if so pull a list of the workspaces and present them
    try:
        from MetasploitProAPI import MetasploitProAPI, MSFProAPIError
        msf = MetasploitProAPI(host=msf_settings['url'],
                               apikey=msf_settings['key'])
    except ImportError as error:
        msf = None

    if msf:
        try:
            msf_reports_res = msf.report_list(
                workspace=msf_settings['workspace'])
        except MSFProAPIError as error:
            msf_reports_res = None

    if msf_reports_res:
        from datetime import datetime
        msf_reports = []
        for rpt in list(msf_reports_res.keys()):
            report_name = "Generated: %s" % (datetime.strftime(
                datetime.fromtimestamp(msf_reports_res[rpt]['created_at']),
                "%m-%d-%y %H:%M:%S"))
            msf_reports.append([rpt, report_name])
        fields.append(
            Field('f_msf_report',
                  type='string',
                  label=T('MSF Pro Report'),
                  requires=IS_EMPTY_OR(IS_IN_SET(msf_reports, zero=None))))

    fields.append(
        Field('f_engineer',
              type='integer',
              label=T('Engineer'),
              default=auth.user.id,
              requires=IS_IN_SET(userlist)))
    fields.append(
        Field('f_asset_group',
              type='string',
              label=T('Asset Group for new Hosts'),
              default="Metasploit Import",
              requires=IS_NOT_EMPTY()))
    fields.append(
        Field('f_include_list', type='text', label=T('Hosts to Only Include')))
    fields.append(
        Field('f_ignore_list', type='text', label=T('Hosts to Ignore')))
    fields.append(
        Field('f_update_hosts',
              type='boolean',
              default=True,
              label=T('Update Existing Hosts')))
    fields.append(
        Field('f_taskit',
              type='boolean',
              default=auth.user.f_scheduler_tasks,
              label=T('Run in background task')))
    form = SQLFORM.factory(*fields, table_name='metasploit_xml')

    if form.errors:
        response.flash = 'Error in form'
    elif form.accepts(request.vars, session):
        # build the hosts only/exclude list
        ip_exclude = []
        data = form.vars.get('f_ignore_list')
        if data:
            ip_exclude = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals
        ip_include = []
        data = form.vars.get('f_include_list')
        if data:
            ip_include = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals

        if form.vars.f_msf_report:
            try:
                msf_report = msf.report_download(rptid=form.vars.f_msf_report)
            except MSFProAPIError as error:
                error = "Unable to download report from Metasploit Pro: %s" % (
                    str(error))
                return dict(form=form, alert=True, error=error)
            check_datadir(request.folder)
            filename = os.path.join(
                filedir, "msfpro-%s-%s.xml" %
                (msf_settings['workspace'], int(time.time())))
            fout = open(filename, "w")
            fout.write(msf_report['data'])
            fout.close()
            del (msf_report)
        else:
            filename = os.path.join(filedir, form.vars.f_filename)

        if form.vars.f_taskit:
            task = scheduler.queue_task(
                scanner_import,
                pvars=dict(
                    scanner='metasploit',
                    filename=filename,
                    asset_group=form.vars.f_asset_group,
                    engineer=form.vars.f_engineer,
                    ip_ignore_list=ip_exclude,
                    ip_include_list=ip_include,
                    update_hosts=form.vars.f_update_hosts,
                ),
                group_name=settings.scheduler_group_name,
                sync_output=5,
                timeout=settings.scheduler_timeout)
            if task.id:
                redirect(URL('tasks', 'status', args=task.id))
            else:
                response.flash = "Error submitting job: %s" % (task.errors)
        else:
            from skaldship.metasploit.pro import process_report_xml
            logger.info("Starting Metasploit XML Import")
            result = process_report_xml(
                filename=filename,
                asset_group=form.vars.f_asset_group,
                engineer=form.vars.f_engineer,
                ip_ignore_list=ip_exclude,
                ip_include_list=ip_include,
                update_hosts=form.vars.f_update_hosts,
            )
            response.flash = result
            redirect(URL('default', 'index'))

    return dict(form=form, alert=alert, error=error)
コード例 #21
0
ファイル: nmap.py プロジェクト: caoimhinp/Kvasir
def nmap_scan():
    """
    Run nmap scan and hand file over to parser
    """
    from skaldship.general import check_datadir
    import time
    import os

    response.title = "%s :: Run Nmap Scan" % (settings.title)

    scan_profiles = {
        'Ping Scan': ["-sn"],
        'Intense Scan': ["-T4", "-A", "-v"],
        'Intense Scan (All TCP Ports)': ["-p", "1-65535", "-T4", "-A", "-v"],
        'Intense Scan (No Ping)': ["-T4", "-A", "-v", "-Pn"],
        'Quick Scan': ["-T4", "-F"],
        'Quick Scan Plus': ["-sV", "-T4", "-O", "-F", "--version-light"],
        'Slow Comprehensive Scan': ["-sS", "-sU", "-T4", "-A", "-v", "-PE", "-PP", "-PS80,443", "-PA3389", "-PU40125", "-PY", "-g 53", "--script", "default"]
    }

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

    fields.append(Field('f_engineer', type='integer', label=T('Engineer'), default=auth.user.id, requires=IS_IN_SET(userlist)))
    fields.append(Field('f_asset_group', type='string', label=T('Asset Group'), requires=IS_NOT_EMPTY()))
    fields.append(Field('f_scan_profile', label=T('Scan Profile'),
                        requires=IS_EMPTY_OR(IS_IN_SET(sorted(scan_profiles.keys()), zero=None))))
    fields.append(Field('f_scan_options', type='string', label=T('Scan Options')))
    fields.append(Field('f_target_list', type='text', label=T('Scan Targets')))
    fields.append(Field('f_blacklist', type='text', label=T('Blacklist')))
    fields.append(Field('f_addnoports', type='boolean', label=T('Add Hosts w/o Ports'), default=False))
    fields.append(Field('f_update_hosts', type='boolean', label=T('Update Host Information'), default=False))

    form = SQLFORM.factory(*fields, table_name='nmap_scan')

    if form.errors:
        response.flash = 'Error in form'
    elif form.accepts(request.vars, session):
        # process a nmap scan
        # build the hosts only/exclude list
        ip_blacklist = []
        data = form.vars.get('f_blacklist')
        if data:
            ip_blacklist = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals
        ip_targets = []
        data = form.vars.get('f_target_list')
        if data:
            ip_targets = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals

        if form.vars.f_scan_options:
            scan_options = form.vars.f_scan_options.split(' ')
        else:
            scan_options = scan_profiles[form.vars.f_scan_profile]

        check_datadir(request.folder)
        filename = "nmap-%s-%s.xml" % (form.vars.f_asset_group, int(time.time()))
        filedir = os.path.join(request.folder, 'data', 'scanfiles', filename)
        scan_options.extend(['--stats-every', '5s', '-oX', filedir])

        task = scheduler.queue_task(
            run_scanner,
            pvars=dict(
                scanner='nmap',
                asset_group=form.vars.f_asset_group,
                engineer=form.vars.f_engineer,
                target_list=ip_targets,
                blacklist=ip_blacklist,
                scan_options=scan_options,
                addnoports=form.vars.f_addnoports,
                update_hosts=form.vars.f_update_hosts,
            ),
            group_name=settings.scheduler_group_name,
            sync_output=5,
            timeout=settings.scheduler_timeout
        )

        if task.id:
            redirect(URL('tasks', 'status', args=task.id))
        else:
            response.flash = "Error submitting job: %s" % (task.errors)

    return dict(form=form)
コード例 #22
0
def import_xml_scan():
    """
    Upload/import Nexpose XML Scan file via scheduler task
    """
    from NexposeAPI import NexposeAPI, Sites, Report
    from skaldship.general import check_datadir
    from skaldship.metasploit import msf_get_config
    import time
    import os
    msf_settings = msf_get_config(session)
    try:
        # check to see if we have a Metasploit RPC instance configured and talking
        from MetasploitProAPI import MetasploitProAPI
        msf_api = MetasploitProAPI(host=msf_settings['url'],
                                   apikey=msf_settings['key'])
        working_msf_api = msf_api.login()
    except:
        working_msf_api = False

    filedir = os.path.join(request.folder, 'data', 'scanfiles')
    response.title = "%s :: Import Nexpose XML Scan Results" % (settings.title)
    fields = []

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

    # check to see if nexpose is configured/active and get site listing
    nexpose_config = nexpose_get_config()
    nxsitelist = []
    if nexpose_config['host'] is not None and nexpose_config[
            'user'] is not None:
        # see if the host is open/active first
        if nexpose_config['host'] is not None:
            sites = Sites()
            sites.host = nexpose_config['host']
            sites.port = nexpose_config['port']
            try:
                if sites.login(user_id=nexpose_config['user'],
                               password=nexpose_config['password']):
                    sites = sites.listings()
                    nxsitelist.append([0, None])
                    for k, v in sites.items():
                        nxsitelist.append([int(k), sites[k]['name']])
            except Exception as e:
                pass

    if nxsitelist:
        fields.append(
            Field('f_nexpose_site',
                  type='integer',
                  label=T('Nexpose Site'),
                  requires=IS_IN_SET(nxsitelist, zero=None)))

    fields.append(
        Field('f_filename',
              'upload',
              uploadfolder=filedir,
              label=T('Nexpose XML File')))
    fields.append(
        Field('f_engineer',
              type='integer',
              label=T('Engineer'),
              default=auth.user.id,
              requires=IS_IN_SET(userlist)))
    fields.append(
        Field('f_asset_group',
              type='string',
              label=T('Asset Group'),
              requires=IS_NOT_EMPTY()))

    # If Metasploit available, pull a list of the workspaces and present them
    if working_msf_api:
        msf_workspaces = []
        msf_workspaces.append("None")
        for w in list(msf_api.pro_workspaces().keys()):
            msf_workspaces.append(w)
        fields.append(
            Field('f_msf_workspace',
                  type='string',
                  label=T('MSF Pro Workspace'),
                  requires=IS_EMPTY_OR(IS_IN_SET(msf_workspaces, zero=None))))

    fields.append(
        Field('f_include_list', type='text', label=T('Hosts to Only Include')))
    fields.append(
        Field('f_ignore_list', type='text', label=T('Hosts to Ignore')))
    fields.append(
        Field('f_update_hosts',
              type='boolean',
              label=T('Update Host Information'),
              default=False))
    fields.append(
        Field('f_taskit',
              type='boolean',
              default=auth.user.f_scheduler_tasks,
              label=T('Run in background task')))
    form = SQLFORM.factory(*fields, table_name='nexpose_xml')

    # form processing
    if form.errors:
        response.flash = 'Error in form'
    elif form.accepts(request.vars, session):
        # process a nexpose file
        if not nxsitelist:
            nexpose_site = '0'
        else:
            nexpose_site = form.vars.f_nexpose_site

        if nexpose_site != '0':
            report = Report()
            report.host = nexpose_config['host']
            report.port = nexpose_config['port']
            nx_loggedin = report.login(user_id=nexpose_config['user'],
                                       password=nexpose_config['password'])
            if nx_loggedin:
                # have nexpose generate the adhoc report
                check_datadir(request.folder)
                filename = os.path.join(
                    filedir,
                    "%s-%s.xml" % (form.vars.f_asset_group, int(time.time())))
                fout = open(filename, "w")
                fout.write(report.adhoc_generate(filterid=nexpose_site))
                fout.close()
            else:
                response.flash = "Unable to login to Nexpose"
                return dict(form=form)
        else:
            filename = form.vars.f_filename
            filename = os.path.join(filedir, form.vars.f_filename)

        # build the hosts only/exclude list
        ip_exclude = []
        data = form.vars.get('f_ignore_list')
        if data:
            ip_exclude = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals
        ip_include = []
        data = form.vars.get('f_include_list')
        if data:
            ip_include = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals

        if form.vars.f_msf_workspace:
            msf_workspace = form.vars.f_msf_workspace
            if msf_workspace == "None":
                msf_workspace = None
        else:
            msf_workspace = None
        msf_settings = {
            'workspace': msf_workspace,
            'url': msf_settings['url'],
            'key': msf_settings['key']
        }

        if form.vars.f_taskit:
            task = scheduler.queue_task(
                scanner_import,
                pvars=dict(
                    scanner='nexpose',
                    filename=filename,
                    asset_group=form.vars.f_asset_group,
                    engineer=form.vars.f_engineer,
                    msf_settings=msf_settings,
                    ip_ignore_list=ip_exclude,
                    ip_include_list=ip_include,
                    update_hosts=form.vars.f_update_hosts,
                ),
                group_name=settings.scheduler_group_name,
                sync_output=5,
                timeout=settings.scheduler_timeout)
            if task.id:
                redirect(URL('tasks', 'status', args=task.id))
            else:
                response.flash = "Error submitting job: %s" % (task.errors)
        else:
            from skaldship.nexpose import process_xml
            log("Starting Nexpose XML Import")
            process_xml(
                filename=filename,
                asset_group=form.vars.f_asset_group,
                engineer=form.vars.f_engineer,
                msf_settings=msf_settings,
                ip_ignore_list=ip_exclude,
                ip_include_list=ip_include,
                update_hosts=form.vars.f_update_hosts,
            )
            response.flash = "Nexpose XML upload complete"
            redirect(URL('default', 'index'))

    return dict(form=form)
コード例 #23
0
ファイル: nmap.py プロジェクト: caoimhinp/Kvasir
def import_xml_scan():
    """
    Upload/import Nmap XML Scan file via scheduler task
    """
    import time
    from skaldship.general import check_datadir
    from skaldship.metasploit import msf_get_config
    msf_settings = msf_get_config(session)

    try:
        # check to see if we have a Metasploit RPC instance configured and talking
        from MetasploitProAPI import MetasploitProAPI
        msf_api = MetasploitProAPI(host=msf_settings['url'], apikey=msf_settings['key'])
        working_msf_api = msf_api.login()
    except:
        working_msf_api = False

    filedir = os.path.join(request.folder,'data','scanfiles')
    check_datadir(request.folder)
    response.title = "%s :: Import Nmap XML Scan Results" % (settings.title)

    fields = []

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

    fields.append(Field('f_filename', 'upload', uploadfolder=filedir, label=T('Nmap XML File')))
    fields.append(Field('f_engineer', type='integer', label=T('Engineer'), default=auth.user.id, requires=IS_IN_SET(userlist)))
    fields.append(Field('f_asset_group', type='string', label=T('Asset Group'), requires=IS_NOT_EMPTY()))

    # If Metasploit available, pull a list of the workspaces and present them
    if working_msf_api:
        msf_workspaces = []
        msf_workspaces.append( "None" )
        for w in msf_api.pro_workspaces().keys():
            msf_workspaces.append(w)
        fields.append(Field('f_msf_workspace', type='string', label=T('MSF Pro Workspace'), requires=IS_EMPTY_OR(IS_IN_SET(msf_workspaces, zero=None))))

    fields.append(Field('f_addnoports', type='boolean', label=T('Add Hosts w/o Ports'), default=False))
    fields.append(Field('f_include_list', type='text', label=T('Hosts to Only Include')))
    fields.append(Field('f_ignore_list', type='text', label=T('Hosts to Ignore')))
    fields.append(Field('f_update_hosts', type='boolean', label=T('Update Host Information'), default=False))
    fields.append(Field('f_taskit', type='boolean', default=auth.user.f_scheduler_tasks, label=T('Run in background task')))
    form = SQLFORM.factory(*fields, table_name='nmap_xml')

    if form.errors:
        response.flash = 'Error in form'
    elif form.accepts(request.vars, session):
        # process a nmap file
        filename = os.path.join(filedir, form.vars.f_filename)

        # build the hosts only/exclude list
        ip_exclude = []
        data = form.vars.get('f_ignore_list')
        if data:
            ip_exclude = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals
        ip_include = []
        data = form.vars.get('f_include_list')
        if data:
            ip_include = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals

        if form.vars.f_msf_workspace:
            msf_workspace = form.vars.f_msf_workspace
            if msf_workspace == "None":
                msf_workspace = None
        else:
            msf_workspace = None
        msf_settings = {'workspace': msf_workspace, 'url': msf_settings['url'], 'key': msf_settings['key']}

        if form.vars.f_taskit:
            task = scheduler.queue_task(
                scanner_import,
                pvars=dict(
                    scanner='nmap',
                    filename=filename,
                    addnoports=form.vars.f_addnoports,
                    asset_group=form.vars.f_asset_group,
                    engineer=form.vars.f_engineer,
                    msf_settings=msf_settings,
                    ip_ignore_list=ip_exclude,
                    ip_include_list=ip_include,
                    update_hosts=form.vars.f_update_hosts,
                ),
                group_name=settings.scheduler_group_name,
                sync_output=5,
                timeout=settings.scheduler_timeout
            )
            if task.id:
                redirect(URL('tasks', 'status', args=task.id))
            else:
                response.flash = "Error submitting job: %s" % (task.errors)
        else:
            from skaldship.nmap import process_xml
            print("Starting Nmap XML Import")
            process_xml(
                filename=filename,
                addnoports=form.vars.f_addnoports,
                asset_group=form.vars.f_asset_group,
                engineer=form.vars.f_engineer,
                msf_settings=msf_settings,
                ip_ignore_list=ip_exclude,
                ip_include_list=ip_include,
                update_hosts=form.vars.f_update_hosts,
            )
            response.flash = "Nmap XML upload complete"
            redirect(URL('default', 'index'))

    return dict(form=form)
コード例 #24
0
def nmap_scan():
    """
    Run nmap scan and hand file over to parser
    """
    from skaldship.general import check_datadir
    import time
    import os

    response.title = "%s :: Run Nmap Scan" % (settings.title)

    scan_profiles = {
        'Ping Scan': ["-sn"],
        'Intense Scan': ["-T4", "-A", "-v"],
        'Intense Scan (All TCP Ports)': ["-p", "1-65535", "-T4", "-A", "-v"],
        'Intense Scan (No Ping)': ["-T4", "-A", "-v", "-Pn"],
        'Quick Scan': ["-T4", "-F"],
        'Quick Scan Plus': ["-sV", "-T4", "-O", "-F", "--version-light"],
        'Slow Comprehensive Scan': [
            "-sS", "-sU", "-T4", "-A", "-v", "-PE", "-PP", "-PS80,443",
            "-PA3389", "-PU40125", "-PY", "-g 53", "--script", "default"
        ]
    }

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

    fields.append(
        Field('f_engineer',
              type='integer',
              label=T('Engineer'),
              default=auth.user.id,
              requires=IS_IN_SET(userlist)))
    fields.append(
        Field('f_asset_group',
              type='string',
              label=T('Asset Group'),
              requires=IS_NOT_EMPTY()))
    fields.append(
        Field('f_scan_profile',
              label=T('Scan Profile'),
              requires=IS_EMPTY_OR(
                  IS_IN_SET(sorted(scan_profiles.keys()), zero=None))))
    fields.append(
        Field('f_scan_options', type='string', label=T('Scan Options')))
    fields.append(Field('f_target_list', type='text', label=T('Scan Targets')))
    fields.append(Field('f_blacklist', type='text', label=T('Blacklist')))
    fields.append(
        Field('f_addnoports',
              type='boolean',
              label=T('Add Hosts w/o Ports'),
              default=False))
    fields.append(
        Field('f_update_hosts',
              type='boolean',
              label=T('Update Host Information'),
              default=False))

    form = SQLFORM.factory(*fields, table_name='nmap_scan')

    if form.errors:
        response.flash = 'Error in form'
    elif form.accepts(request.vars, session):
        # process a nmap scan
        # build the hosts only/exclude list
        ip_blacklist = []
        data = form.vars.get('f_blacklist')
        if data:
            ip_blacklist = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals
        ip_targets = []
        data = form.vars.get('f_target_list')
        if data:
            ip_targets = data.split('\r\n')
            # TODO: check for ip subnet/range and break it out to individuals

        if form.vars.f_scan_options:
            scan_options = form.vars.f_scan_options.split(' ')
        else:
            scan_options = scan_profiles[form.vars.f_scan_profile]

        check_datadir(request.folder)
        filename = "nmap-%s-%s.xml" % (form.vars.f_asset_group, int(
            time.time()))
        filedir = os.path.join(request.folder, 'data', 'scanfiles', filename)
        scan_options.extend(['--stats-every', '5s', '-oX', filedir])

        task = scheduler.queue_task(run_scanner,
                                    pvars=dict(
                                        scanner='nmap',
                                        asset_group=form.vars.f_asset_group,
                                        engineer=form.vars.f_engineer,
                                        target_list=ip_targets,
                                        blacklist=ip_blacklist,
                                        scan_options=scan_options,
                                        addnoports=form.vars.f_addnoports,
                                        update_hosts=form.vars.f_update_hosts,
                                    ),
                                    group_name=settings.scheduler_group_name,
                                    sync_output=5,
                                    timeout=settings.scheduler_timeout)

        if task.id:
            redirect(URL('tasks', 'status', args=task.id))
        else:
            response.flash = "Error submitting job: %s" % (task.errors)

    return dict(form=form)
コード例 #25
0
ファイル: accounts.py プロジェクト: KvasirSecurity/Kvasir
def paste():
    """
    Import and parse password pasted to a textbox into t_accounts
    """
    from skaldship.general import check_datadir
    check_datadir(request.folder)

    # Service_id is primary, host_id is secondary, if none then list
    # all the services
    svc_set = []
    url=URL('accounts', 'paste')
    if request.vars.has_key('service_id'):
        try:
            record = db.t_services[request.vars.service_id]
            svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number)))
            url = URL('accounts', 'paste', vars={'service_id':request.vars.service_id})
        except:
            pass
    elif request.vars.has_key('host_id'):
        try:
            host_record = get_host_record(request.vars.host_id)
            svc_records = db(db.t_services.f_hosts_id == host_record.id).select(cache=(cache.ram, 30))
            url = URL('accounts', 'paste', vars={'host_id':request.vars.host_id})
            for record in svc_records:
                svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number)))
        except:
            pass

    if len(svc_set) == 0:
        # all services
        svc_records = db(db.t_services).select(cache=(cache.ram,30))
        svc_set = []
        for record in svc_records:
            svc_set.append((record.id, "%s :: %s/%s" % (host_title_maker(db.t_hosts[record.f_hosts_id]), record.f_proto, record.f_number)))

    if request.extension == "load":
        buttons=[]
    else:
        buttons=['submit']

    form = SQLFORM.factory(
        Field('f_service', 'string', label=T('Host / Service'), requires=IS_IN_SET(svc_set), default=svc_set[0][0]),
        Field('f_pwtext', 'text', label=T('Password text')),
        Field('f_type', 'string', label=T('File type'), default='PWDUMP', requires=IS_IN_SET(settings.password_file_types)),
        Field('f_source', 'string', label=T('Source (if necessary)')),
        Field('f_add_to_evidence', 'boolean', label=T('Add file to Evidence')),
        buttons=buttons, _action=url, _id='accounts_paste_form'
        #_action=url, _id='accounts_paste_form', formstyle='bootstrap_modal'
    )

    resp_text = ""
    accounts_added = []
    accounts_updated = []
    if form.errors:
        response.flash = 'Error in form'
        return TABLE(*[TR(k, v) for k, v in form.errors.items()])
    elif form.accepts(request.vars, session):
        from gluon.utils import web2py_uuid
        host_id = db.t_services[form.vars.f_service].f_hosts_id
        pwd_file_dir = os.path.join(request.folder, 'data', 'passwords', 'other')
        if not os.path.exists(pwd_file_dir):
            from gluon.fileutils import mktree
            mktree(pwd_file_dir)
        filename = "%s-pwfile-%s" % (host_id, web2py_uuid())
        full_file_path = os.path.join(request.folder, 'data/passwords/other', filename)
        of = open(full_file_path, "w")
        of.write(form.vars.f_pwtext)
        of.close()

        logger.debug("Processing password file: %s" % (full_file_path))
        account_data = process_password_file(pw_file=full_file_path, file_type=request.vars.f_type, source=request.vars.f_source)
        response.headers['web2py-component-command'] = 'accounttable.fnReloadAjax();'
        resp_text = insert_or_update_acct(form.vars.f_service, account_data)

        if form.vars.f_add_to_evidence is True:
            # add the password file to evidence
            try:
                pwdata = open(full_file_path, "r").readlines()
            except Exception, e:
                logger.error("Error opening %s: %s" % (full_file_path, e))
                resp_text += "Error opening %s: %s\n" % (full_file_path, e)

            db.t_evidence.insert( f_hosts_id = host_id,
                                  f_type = 'Password File',
                                  f_text = form.vars.f_type,
                                  f_filename = filename,
                                  f_evidence = filename,
                                  f_data = pwdata)
            resp_text += "\n%s added to evidence\n" % (filename)
            db.commit()
コード例 #26
0
ファイル: scheduler.py プロジェクト: KvasirSecurity/Kvasir
def launch_terminal(record=None, launch_cmd=None):
    """
    Opens a terminal on the Web Server. This only works if the
    web2py server is running on the user's workstation.

    The command to execute is stored in the user's settings db
    under auth_user.f_launch_cmd. Variables translated:

       _IP_      -- The current IP Address (v4 by default, v6 if exists)
       _LOGFILE_ -- Session logfile name (we prepend the path)

    If an IPv6 address is used then ':' is changed to '_'

    Example:

    xterm -sb -sl 1500 -vb -T 'manual hacking: _IP_' -n 'manual hacking: _IP_' -e script _LOGFILE_
    """

    record = get_host_record(record)

    # only execute launch on requests from localhost!
    if request.env['remote_addr'] != '127.0.0.1':
        logger.error("Can only launch from localhost! remote_addr = %s" % (request.env['remote_addr']))
        return "Can only launch from localhost"

    if record is None:
        return "No record found"

    import string, os, subprocess
    import time
    from gluon.validators import IS_IPADDRESS

    # if no launch command use the default
    if not launch_cmd:
        launch_cmd = "xterm -sb -sl 1500 -vb -T 'manual hacking: _IP_' -n 'manual hacking: _IP_' -e 'script _LOGFILE_'"

    # check ip address
    ip = record.f_ipaddr
    logip = ip
    if IS_IPADDRESS(is_ipv6=True)(ip)[0] == None:
        logip = ip.replace(":", "_")

    logdir = "session-logs"
    logfilename = "%s-%s.log" % (logip, time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())))
    logfile = os.path.join(logdir, logfilename)
    launch_cmd = launch_cmd.replace("_IP_", ip)
    launch_cmd = launch_cmd.replace("_LOGFILE_", logfile)

    from skaldship.general import check_datadir
    # Check to see if data directories exist, create otherwise
    check_datadir(request.folder)
    datadir = os.path.join(os.getcwd(), request.folder, "data")

    # chdir to datadir!
    launch_cmd = launch_cmd.replace("_DATADIR_", datadir)
    os.chdir(datadir)

    # set environment variables
    os.environ['IP'] = ip
    os.environ['HOSTNAME'] = record.f_hostname or ""
    os.environ['DATADIR'] = datadir

    try:
        logger.info("Spawning: %s\n" % (launch_cmd))
        print("Spawning: %s" % (launch_cmd))
        subprocess.Popen(launch_cmd, shell=True)#, stdout=None, stdin=None, stderr=None)
    except Exception, e:
        logger.error("Error spawning launch cmd (%s): %s\n" % (launch_cmd, e))
        print("Error spawning launch cmd (%s): %s\n" % (launch_cmd, e))