Skip to content

Repository files navigation

KROFT Security Matrix

A self-hosted, single-operator network reconnaissance and exploitation console. Kroft wraps three things behind one dark-themed web UI:

  1. nmap — for asset discovery and service/OS fingerprinting.
  2. Metasploit Framework (via its RPC daemon, msfrpcd) — for module search, exploitation, post-exploitation, session handling, and an interactive console.
  3. OpenVAS / Greenbone (via GMP) — an authenticated vulnerability scanner that finds CVE-backed weaknesses on discovered hosts and feeds them into the asset inventory, engagement reports, and Kroft.AI's attack planning.
  4. Kroft.AI — an in-browser LLM advisor (backed by Ollama) that reads your recon data and the OpenVAS findings, suggests real, verified MSF modules, explains output, and can run a guided autonomous "autopilot" loop.

Everything an engagement produces — discovered hosts, exploit attempts, captured loot — is stored in a local SQLite database so it survives restarts and can be exported.

⚠️ Authorized use only. Kroft is built for security testing of systems you own or are explicitly authorized to assess. A configurable scope guardrail blocks intrusive actions against out-of-scope hosts, but it is a safety net, not a substitute for authorization.


Table of contents


Features

The UI is a single page with ten tabs, each backed by a slice of the API:

Tab What it does
Asset Matrix The host inventory. Lists every discovered host with ports, OS guess, MAC, tags, last-seen time, and a vulnerability badge (count + max CVSS from OpenVAS). Supports tagging, deletion, CSV/JSON export, and a one-click "run vuln scan" action per host.
Advanced Scanner Launches nmap scans with an allow-listed set of flags. Scans run in the background; progress is polled.
Vuln Scanner Launches OpenVAS / Greenbone scans against a target (scope-guarded, background job with live phase/progress). Findings land in a severity-ranked table with CVSS, CVE links, and remediation, and can be handed to Kroft.AI ("Analyze with AI" / per-finding "find exploits").
Findings & Loot Credentials, hashes, keys, and other findings, de-duplicated and attributable to a host/source.
Pentest Console Search MSF exploit modules, inspect their options/payloads, and dispatch them at a target.
Active Shells Lists live shell/meterpreter sessions and lets you run commands in them.
Kroft.AI An LLM advisor + autonomous agent. Grounds its suggestions in real modules via the suggest/validate endpoints, can execute MSF command blocks, and analyzes the output.
Cyberspace A 3D, real-time visualization of the engagement (three.js): your network floats as glowing nodes around the Kroft core, the AI agent buzzes between them scanning/exploiting, owned hosts turn green and pivot, and DB activity streaks packets to/from the core. Includes a scrubbable timeline to replay everything. Purely cosmetic — a window onto the real tools.
Post / Auxiliary Console Runs post and auxiliary modules and captures their output.
MSF Console A full interactive msf6 > terminal in the browser (xterm.js).

Supporting capabilities: CVE enrichment (NVD lookups for a product/version), OpenVAS vulnerability findings woven into the matrix / reports / AI context, engagement scope enforcement, and persistent storage of all of the above.


Architecture

Kroft is a Flask application organized in three layers, plus background workers and the external services it orchestrates.

                         Browser (single-page UI, Tailwind + xterm.js)
                                          │  fetch() / JSON
                                          │  (Kroft.AI talks to Ollama directly)
   ┌──────────────────────────────────────┼───────────────────────────────────┐
   │  Flask app (kroft/)                   ▼                                    │
   │                                                                           │
   │   ROUTES  (kroft/routes/*)   ── thin HTTP handlers, one blueprint/domain  │
   │      main · hosts · scans · settings · loot · reports · cve · ollama      │
   │      openvas · msf/{status,modules,exploit,sessions,console}              │
   │        │                                                                  │
   │        ▼                                                                  │
   │   SERVICES (kroft/services/*) ── the heavy lifting                        │
   │      nmap_scanner · msf_client · msf_console · msf_modules · msf_workers  │
   │      gvm_client · openvas_scanner                                         │
   │        │                    │                     │              │        │
   │        ▼                    ▼                     ▼              ▼        │
   │   CORE (kroft/*)      background threads    MSF RPC client   GVM/GMP      │
   │      database/models      (run_scan,        (auto-reconnect)  client      │
   │      state (registries)    run_exploit,     run_openvas_scan             │
   │      settings_store        run_post_module)                              │
   │      scope                                                                │
   └───────────────────────────────────────────────────────────────────────────┘
        │                          │                  │                 │
        ▼                          ▼                  ▼                 ▼
   SQLite (kroft_assets.db)    nmap binary   msfrpcd (MSF RPC)   openvas (GVM/GMP)

Design principles

  • Routes stay thin. Each blueprint just validates input and calls a service; it never embeds business logic.
  • Services own one concern each. All Metasploit RPC quirks, nmap argument handling, and worker logic live in kroft/services/, isolated and testable.
  • Long-running work runs off-thread. Scans and exploits are dispatched to daemon threads that record progress in in-memory registries; the UI polls for status. The HTTP request returns immediately with a job_id.
  • The MSF connection is managed centrally. One background thread keeps the RPC connection alive; everything else calls get_msf() to grab a live client (or None) without ever blocking.
  • An application factory (create_app()) builds and wires everything, so the app is import-safe and easy to configure.

Project structure

.
├── app.py                      # Entry point: create_app().run()  (Docker CMD targets this)
├── kroft/                      # The application package
│   ├── __init__.py             # create_app() application factory
│   ├── config.py               # Env-driven configuration (DB, MSF, OpenVAS/GVM, Ollama, server)
│   ├── database.py             # SQLAlchemy engine, Session factory, init_db() + migrations
│   ├── models.py               # ORM models: Host, ExploitLog, Loot, Vulnerability, Setting
│   ├── settings_store.py       # get_setting / set_setting (key-value store)
│   ├── state.py                # In-memory registries + locks (jobs, sessions, consoles)
│   ├── scope.py                # Engagement scope guardrail (in_scope)
│   ├── events.py               # In-memory ring buffer of activity events (for the visualizer)
│   ├── activity.py             # after_request hook: maps DB/action routes -> events
│   ├── services/               # Service layer — the heavy lifting
│   │   ├── nmap_scanner.py     #   nmap arg allow-list, conflict resolution, port-merge, run_scan worker
│   │   ├── msf_client.py       #   auto-reconnecting MSF RPC connection manager + get_msf()
│   │   ├── msf_console.py      #   safe wrappers around the msfrpcd console API + banner stripping
│   │   ├── msf_modules.py      #   module search / validate / suggest, compatible payloads
│   │   ├── msf_workers.py      #   run_exploit + run_post_module background workers
│   │   ├── gvm_client.py       #   OpenVAS/GVM connection manager + gmp_session() helper
│   │   └── openvas_scanner.py  #   run_openvas_scan worker: GMP scan lifecycle + report parsing
│   └── routes/                 # HTTP layer — one Flask blueprint per domain
│       ├── __init__.py         #   register_blueprints(app)
│       ├── main.py             #   GET /                       (serves the UI)
│       ├── hosts.py            #   /api/hosts*                 (inventory, tags, export)
│       ├── scans.py            #   /api/scan, /api/jobs        (nmap dispatch + status)
│       ├── settings.py         #   /api/settings
│       ├── loot.py             #   /api/loot*
│       ├── reports.py          #   /api/report/<ip>
│       ├── cve.py              #   /api/cve                    (NVD enrichment)
│       ├── openvas.py          #   /api/openvas/*              (vuln scan dispatch, status, findings)
│       ├── ollama.py           #   /api/ollama/models
│       ├── events.py           #   /api/events                 (visualizer event feed)
│       └── msf/                #   /api/msf/* grouped by concern
│           ├── __init__.py     #     shared `bp` blueprint
│           ├── status.py       #     status + db_nmap scan
│           ├── modules.py      #     search / suggest / validate / info
│           ├── exploit.py      #     exploit & post/aux dispatch, jobs, output, logs
│           ├── sessions.py     #     session list / exec / read / kill
│           └── console.py      #     console_exec + interactive console
├── templates/                  # Server-rendered HTML (Jinja2)
│   ├── index.html              # Page shell: <head> + {% include %}s + ordered <script> tags
│   └── partials/               # HTML components, assembled by index.html
│       ├── _styles.html        #   the Tailwind <style> block (kept inline for the CDN JIT)
│       ├── _sidebar.html       #   left-hand navigation
│       ├── _header.html        #   top bar (title, scope indicator, settings)
│       ├── tabs/               #   one file per tab: _matrix, _scanner, _pentest, _shells,
│       │                       #     _msfconsole, _kroftai, _cyberspace, _postaux, _findings, _openvas
│       └── modals/             #   _settings, _report, _job_detail
├── static/                     # Browser assets served at /static
│   └── js/                     # Front-end logic, split by feature, loaded in order
│       ├── 01-core.js          #   globals, clock, tab switching
│       ├── 02-scanner.js       #   nmap scanner + jobs queue
│       ├── 03-matrix.js        #   asset matrix
│       ├── 04-pentest.js       #   pentest console + "Hail Mary"
│       ├── 05-shells.js        #   shells / xterm terminals
│       ├── 06-kroftai.js       #   Kroft.AI: status, chat, analysis
│       ├── 07-ai-commands.js   #   AI command blocks + job-output injection
│       ├── 08-postaux.js       #   post/aux panel, job-detail modal, post/aux console
│       ├── 09-console.js       #   interactive MSF console + Ollama model picker
│       ├── 10-findings.js      #   findings/loot, settings/scope, report
│       ├── 11-extras.js        #   notifications, cred reuse, auto post-recon, CVE
│       ├── 12-autopilot.js     #   autonomous agent loop
│       ├── 13-init.js          #   bootstrap calls on page load
│       ├── 14-cyberspace.js    #   3D visualizer: recorder, scene, choreography, playback
│       └── 15-openvas.js       #   Vuln Scanner tab: launch/poll scans, findings table, AI hand-off
├── kroft_assets.db             # SQLite database (created/updated at runtime)
├── requirements.txt            # Python dependencies
├── Pipfile                     # Pipenv equivalent of requirements
├── Dockerfile                  # Builds the scanner image (installs nmap + deps)
└── docker-compose.yml          # Runs the scanner + Metasploit RPC + OpenVAS containers together

How it works

Data model (kroft/models.py)

Five SQLite-backed tables hold everything persistent:

  • Host — one row per discovered asset: IP, MAC, hostname, OS guess, open ports (both a human-readable string and structured JSON), status, last-seen, user tags, and an OpenVAS rollup (vuln_count, max_severity).
  • ExploitLog — an audit trail: every exploit/auxiliary/post run with its module, options, status, result, and any resulting session id.
  • Loot — findings (credentials, hashes, keys, etc.), de-duplicated on (host_ip, type, value).
  • Vulnerability — OpenVAS/Greenbone findings: NVT name + OID, port, severity/CVSS/threat, CVE IDs, description, remediation, and the report id. De-duplicated on (host_ip, oid, port) so re-scans refresh rather than pile up.
  • Setting — a key/value store; today its main job is the engagement scope_cidr.

init_db() creates the tables on startup and runs tiny migrations that add the tags, vuln_count, and max_severity columns to older hosts tables.

nmap scanning (services/nmap_scanner.py)

A scan request returns a job_id immediately and the work happens in a daemon thread (run_scan):

  1. Sanitize user flags. sanitize_args() tokenizes the input and checks each token (and its value, for flags like -p 80) against ALLOWED_ARG_PATTERN. Anything not on the allow-list is dropped and reported as a warning — raw flags are never passed to nmap.
  2. Resolve conflicts. Mutually exclusive flags (e.g. a ping-sweep -sn alongside -sV) are pruned.
  3. Scan and persist. Discovered hosts are upserted with merge, not clobber semantics: a narrow follow-up scan never erases OS/port/version data a broader earlier scan gathered (merge_ports).

OpenVAS vulnerability scanning (services/gvm_client.py, services/openvas_scanner.py)

Kroft drives a real Greenbone/OpenVAS scanner over GMP — it does not re-implement scanning. Like the MSF integration, it degrades gracefully when the scanner is down or still syncing feeds.

  • gvm_client.py owns the connection. A background thread health-checks GMP every 20s (get_gvm_status() caches {connected, version} for the UI). Work runs through gmp_session(), a context manager that opens a fresh, authenticated TLS session per unit of work — deliberately short-lived so a multi-minute scan can't be killed by an idle-dropped socket. All imports are deferred so the app boots even if python-gvm isn't installed.
  • openvas_scanner.py runs the scan lifecycle in a daemon thread (run_openvas_scan): create target → create task → start → poll to completion (updating openvas_jobs[job_id] with live phase + progress) → fetch the report. parse_report() defensively pulls each finding's NVT name/OID, port, severity/CVSS/threat, CVE refs and remediation; persist_vulns() de-dupes on (host_ip, oid, port) and rolls the counts up onto the Host row (creating a stub host if the asset was only ever seen by the vuln scan). A compact summarize_vulns() string is stored on the job for the job-detail view and the Kroft.AI hand-off.

How the findings make everything else smarter

  • Asset Matrix shows a severity badge (count + max CVSS) per host.
  • Engagement reports (/api/report/<ip>) include the vulnerabilities array, and the report writer is prompted to add a dedicated OpenVAS section.
  • Kroft.AI folds the findings into its recon context: before an analysis, loadHostVulns() primes a per-host cache and buildReconContext() lists the scanner-confirmed vulnerabilities (with CVEs) so the model prioritises real weaknesses over version-banner guesses. Per-finding "find exploits" and the tab-level "Analyze with AI" button pivot straight into a targeted MSF-module ask.

Metasploit integration

This is the most defensively written part of the app, because msfrpcd and the pymetasploit3 client occasionally return a bare bool where a dict/list is expected — which otherwise crashes deep inside the library with "'bool' object is not subscriptable". Kroft sidesteps this throughout:

  • msf_client.py runs one background thread that connects to msfrpcd, health-checks it every 10s by reading core.version, and reconnects on failure. Callers use get_msf() to get a live client instantly or None — they never block.
  • msf_console.py calls the console RPCs directly and validates each response shape, instead of going through msf.consoles.console() (whose manager subscripts an unvalidated response on every call). It also strips the noisy Metasploit startup banner before output is shown or fed to the AI.
  • msf_modules.py validates that a module is loadable before handing its name to modules.use(), and provides "did you mean" suggestions for bad module paths by searching the live module DB.
  • msf_workers.py runs exploits and post/auxiliary modules in daemon threads:
    • run_exploit validates the module, sets options, auto-selects LHOST (the routable IP toward the target) and the best compatible payload (handling bind-shell-only modules specially), executes via the low-level module manager to avoid the library's payload-validation crash, then polls up to 30s for a new session.
    • run_post_module drives a console (useset …run -j), polls for output, strips the banner, and records the result.

Exploit/auxiliary/post dispatch is intentionally routed by module type: auxiliary and post modules must not be loaded as exploit/..., so the exploit endpoint detects those prefixes and sends them to the console-based worker.

In-memory state (state.py)

Live activity that doesn't belong in the database lives in process-wide registries guarded by locks: active_jobs (scans), exploit_jobs (exploit/aux/post), msf_sessions (open sessions), and msf_consoles (interactive terminals). The UI polls the corresponding endpoints to render real-time status.

Kroft.AI

The AI advisor runs in the browser and talks to an Ollama server directly (streaming chat). The Flask backend only exposes /api/ollama/models so the UI can populate its model dropdown. To keep the AI grounded in reality, it uses Kroft's own endpoints as tools:

  • /api/msf/modules/suggest and /validate so it only ever proposes modules that actually exist in your Metasploit install,
  • /api/msf/console_exec to run command blocks (output is banner-stripped and smartly truncated to fit the model's context),
  • /api/report/<ip> to assemble everything known about a host for a write-up.

The autopilot mode wraps this in a loop: choose one action, observe the result, choose the next.

Frontend (no build step)

The UI is plain server-rendered HTML plus vanilla JavaScript — no npm, bundler, or framework. Tailwind and xterm.js load from CDNs, so there is nothing to compile.

  • HTML is composed with Jinja2 includes. templates/index.html is just a shell: the <head>, the page skeleton, and a series of {% include 'partials/…' %} tags. Each tab, modal, the sidebar, and the header live in their own partial under templates/partials/. The Tailwind <style> block stays inline (in _styles.html) because the Tailwind Play CDN compiles it at runtime.
  • JavaScript is split by feature into ordered files under static/js/ (01-core.js13-init.js), loaded with plain <script> tags at the end of the body. They are classic scripts, not ES modules, so they share one global scope — exactly like the original single inline script did. This is what keeps every inline onclick="…" handler working untouched.
  • Load order is the contract. The files are loaded in the same order the code was originally written, and 13-init.js (which kicks off fetchHosts() etc.) runs last, after every function is defined. When editing, keep load-time calls in the file that defines what they use (or in 13-init.js).

Cyberspace visualizer

The Cyberspace tab (static/js/14-cyberspace.js) is a three.js scene driven entirely by Kroft's real telemetry — it scripts nothing. It's cosmetic: a window onto the live tools, safe to ignore.

Two clocks keep it honest:

  • A recorder that's always on. A lightweight poll (every ~2s) of /api/hosts, /api/jobs, /api/msf/jobs, /api/msf/sessions and /api/events runs from page load — even while the tab is hidden — and writes a timestamped timeline: when each host was discovered, its status transitions, session open/close times, and the discrete "something happened" pulses. The timeline is what makes playback possible. The data model is pure (no three.js), so recording never depends on the renderer.
  • A renderer that only runs when visible. The WebGL render loop is started on tab-open and paused on tab-close (no wasted GPU). Each frame it reconstructs the scene at the current playhead time T — which hosts exist, their status colors, which are owned — so the exact same code path serves both live mode (T = now) and replay (T = wherever you dragged the scrubber).

Visual language: hosts are wireframe nodes around the glowing Kroft core; status drives color (blue discovered → amber scanning → red under-attack → green owned); a green AI drone flies to the active target and fires scan/exploit beams at its ports; owned hosts sprout an inner bot and beam pivot traffic to the next victim; and every interesting server action sends a bright packet that slingshots along a slow, decaying gravitational orbit before being swallowed by its destination (CVE lookups arc out to a distant internet node and back). Data that lands in the core (loot, recon, CVE intel) crystallizes into a colored shard that stays inside the core, so it visibly fills up as the engagement progresses. A packet-colour key sits in the HUD, and clicking any host opens a floating 3D dossier that types out its nmap details (click it again to dismiss).

The packet pulses come from the event feed (kroft/events.py): an after_request hook (kroft/activity.py) maps the handful of routes that represent real DB/MSF activity (loot stored, module looked up, CVE queried, exploit dispatched, …) onto a bounded in-memory ring buffer, which the visualizer polls via /api/events. Routine UI polling is deliberately not recorded, so the traffic stays meaningful.

Request lifecycle (example: launching an exploit)

POST /api/msf/exploit {target_ip, module, options}
  → routes/msf/exploit.py: validate input + scope check (scope.in_scope)
  → create exploit_jobs[job_id]; spawn thread → services/msf_workers.run_exploit
  → return {job_id}                                   (immediately)
...meanwhile, the worker thread:
  → validate module, set options, pick payload/LHOST, execute via MSF RPC
  → poll for a new session; update exploit_jobs[job_id] + ExploitLog row
UI polls GET /api/msf/jobs and GET /api/msf/jobs/<job_id>/output for status.

Setup

Option A — Docker Compose (recommended)

This brings up both the Kroft web app and a Metasploit RPC daemon, wired together on a private Docker network.

docker compose up --build

Then open http://localhost:5000.

What Compose starts:

  • msf-rpc — the official metasploitframework/metasploit-framework image running msfrpcd (password msfrpc, port 55553). Its data is persisted to ./msf_data.

  • openvas — the single-container immauss/openvas image, which bundles the whole Greenbone/GVM stack (gvmd, ospd-openvas, the scanner, postgres, redis, feeds) into one service and exposes GMP on 9390 and the Greenbone web UI (GSA) on 9392. Kroft talks to it over GMP/TLS. Its feed DB is persisted to the openvas_data volume.

    ⚠️ First boot is slow. OpenVAS downloads its vulnerability feeds on the initial run — this can take 15–30+ minutes and a few GB of disk. Until the sync finishes the Vuln Scanner tab shows the scanner offline and scans return a "not reachable yet" error; the rest of Kroft works normally. The openvas_data volume means this only happens once.

  • kroft-scanner — this app, built from the Dockerfile (which installs nmap and the Python deps). It is configured via environment variables to reach the RPC + OpenVAS containers and runs privileged so nmap can perform OS detection / raw socket scans.

Option B — Run locally

Prerequisites: Python 3.10+, the nmap binary, and a running msfrpcd if you want the Metasploit features.

# 1. System dependency
sudo apt-get install -y nmap            # (or your platform's package manager)

# 2. Python dependencies
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

# 3. (Optional) start the Metasploit RPC daemon
msfrpcd -P msfrpc -S -a 127.0.0.1 -p 55553 -f

# 4. Run Kroft
python app.py

Open http://localhost:5000. The app starts fine without Metasploit or OpenVAS — those features simply report "not connected" / "offline" until the respective service is reachable. (OpenVAS is heavy to run standalone; Docker Compose is the recommended way to bring it up. Point GVM_HOST/GVM_PORT at any GMP endpoint.)

Note: OS detection and some scan types require root/raw-socket privileges. Run with appropriate privileges (or via the privileged Docker container).

Dev vs. debug: python app.py runs with debug off by default (production-safe). For the auto-reloader and interactive debugger while developing, set KROFT_DEBUG=1 — but never in production (Werkzeug's debugger is a remote-code-execution console).

Running in production

Two constraints drive how Kroft must be deployed:

  1. Single process, always. Live state (scan jobs, exploit jobs, sessions, consoles) lives in in-memory registries (kroft/state.py). Threads are fine, but multiple worker processes are not — each would get its own copy and the UI would see jobs/sessions blink in and out. Run exactly one worker.
  2. Debug off. Ensure KROFT_DEBUG is unset or 0.

app is the WSGI callable, so put a single-worker production server in front of the Flask dev server:

# gunicorn: one worker, many threads (threads carry the concurrency)
gunicorn --workers 1 --threads 8 --timeout 120 app:app

# …or waitress (no system deps)
waitress-serve --threads=8 --listen=0.0.0.0:5000 app:app

Because this is effectively a remote-controlled exploitation platform, also put it behind authentication / a VPN and bind it to a trusted interface — see Security notes.


Configuration

All configuration is via environment variables (see kroft/config.py); every one has a working default.

Variable Default Purpose
MSF_HOST 127.0.0.1 Host of the Metasploit RPC daemon.
MSF_PORT 55553 Port of msfrpcd.
MSF_PASSWORD msfrpc RPC password.
GVM_HOST 127.0.0.1 Host of the OpenVAS/Greenbone GMP endpoint (openvas under Compose).
GVM_PORT 9390 GMP (TLS) port.
GVM_USERNAME admin GMP username Kroft authenticates as.
GVM_PASSWORD admin GMP password (keep in sync with the openvas container's PASSWORD).
GVM_SCAN_CONFIG_ID daba56c8-… Scan config UUID (default: Full and fast).
GVM_SCANNER_ID 08b69003-… Scanner UUID (default: OpenVAS default scanner).
GVM_PORT_LIST_ID 33d0cd82-… Port-list UUID (default: All IANA assigned TCP).
OLLAMA_BASE https://ollama.local.craysoftware.com Ollama server used by Kroft.AI (the browser must be able to reach this).
KROFT_DB sqlite:///kroft_assets.db SQLAlchemy database URL.
KROFT_HOST 0.0.0.0 Bind address (used by kroft/config.py; app.py runs on 0.0.0.0:5000).
KROFT_PORT 5000 Port.
KROFT_DEBUG 1 Flask debug flag.

The engagement scope (scope_cidr) is not an environment variable — it is set at runtime in the Settings UI (or via POST /api/settings) and stored in the database. An empty scope allows all targets; otherwise intrusive actions are restricted to the listed CIDR(s).


API reference

All responses are JSON unless noted.

Recon & assets

Method Path Description
GET / The single-page UI.
POST /api/scan Start an nmap scan. Body: {target, custom_args}{job_id}.
GET /api/jobs List nmap scan jobs (most recent first).
GET /api/hosts List all discovered hosts.
DELETE /api/hosts/<id> Delete a host.
POST /api/hosts/<id>/tags Set a host's tags. Body: {tags}.
GET /api/hosts/export?format=csv|json Export the inventory.

Findings, reporting & enrichment

Method Path Description
GET /api/loot[?host=<ip>] List loot (optionally filtered by host).
POST /api/loot Add loot item(s) (deduped). Body: a loot object or {items:[…]}.
DELETE /api/loot/<id> Delete a loot item.
GET /api/report/<ip> Aggregate host + exploit logs + loot + OpenVAS vulns for a report.
GET /api/cve?q=<product+version> NVD CVE lookup (best-effort, cached).
GET/POST /api/settings Read / write the key-value settings (e.g. scope_cidr).

OpenVAS / vulnerability scanner

Method Path Description
GET /api/openvas/status Scanner connection status + GMP version (cached, non-blocking).
GET /api/openvas/configs Available scan configs for the dropdown (falls back to the default).
POST /api/openvas/scan Start a vuln scan. Body: {target, config_id?}{job_id}. (scope-checked)
GET /api/openvas/jobs List vuln-scan jobs with live phase/progress.
GET /api/openvas/jobs/<job_id> One job's detail.
GET /api/openvas/jobs/<job_id>/output The scan's summary text (for the AI feed / job detail).
GET /api/openvas/vulns[?host=<ip>] List findings (most severe first), optionally by host.
DELETE /api/openvas/vulns/<id> Delete a finding.
GET /api/openvas/export?format=csv|json[&host=<ip>] Export findings.

Metasploit

Method Path Description
GET /api/msf/status RPC connection status + version.
POST /api/msf/scan Run db_nmap inside Metasploit. Body: {target}. (scope-checked)
GET /api/msf/modules/search?q=&type= Search modules.
POST /api/msf/modules/suggest Verified module suggestions from recon keywords. Body: {keywords, type}.
GET /api/msf/modules/validate?module=&type= Check a module loads; suggest alternatives if not.
GET /api/msf/modules/info?module=&type= Module options, payloads, references.
POST /api/msf/exploit Dispatch an exploit (or aux/post). Body: {target_ip, module, options}{job_id}. (scope-checked)
POST /api/msf/post Dispatch a post/auxiliary module. Body: {module, options, type}{job_id}.
GET /api/msf/jobs List MSF exploit/aux/post jobs.
GET /api/msf/jobs/<job_id>/output Full captured output for a job.
POST /api/msf/jobs/<job_id>/kill Kill one MSF framework job.
POST /api/msf/jobs/kill_all Kill all MSF framework jobs.
GET /api/msf/exploit_logs Recent exploit log entries (audit trail).
GET /api/msf/sessions List live sessions (synced from MSF).
POST /api/msf/sessions/<sid>/exec Run a command in a session. Body: {cmd}.
GET /api/msf/sessions/<sid>/read Poll a session for unsolicited output.
POST /api/msf/sessions/<sid>/kill Terminate a session.
POST /api/msf/console_exec Run a batch of console commands; returns trimmed output. Body: {commands:[…]}.
POST /api/msf/console/create Create a persistent interactive console.
POST /api/msf/console/<cid>/write Send input to a console. Body: {input}.
GET /api/msf/console/<cid>/read Read pending console output.
POST /api/msf/console/<cid>/destroy Destroy a console.

AI & visualization

Method Path Description
GET /api/ollama/models List models available on the configured Ollama server.
GET /api/events?since=<seq> Activity event feed for the Cyberspace visualizer. Returns {events, last_seq}; poll with the last seq for incremental updates.

Security notes

  • Authorization first. Only use Kroft against systems you own or are authorized to test.
  • Scope guardrail. Set scope_cidr in Settings to restrict intrusive endpoints (/api/msf/scan, /api/msf/exploit) to your authorized range. It guards single hosts; ranges/hostnames are passed through, so define scope carefully.
  • No authentication. The web UI has no built-in auth and binds to 0.0.0.0. Run it only on a trusted, isolated network (or behind your own auth/VPN). Do not expose it to the internet.
  • Debug mode. The development server runs with debug=True. For a real deployment, front it with a production WSGI server and disable debug.
  • Privileged operations. nmap OS detection and Metasploit need elevated privileges; the Docker setup runs the scanner container as privileged.

Development

  • Application factory. kroft/create_app() builds the app: it runs init_db(), starts the background MSF connection manager, and registers all blueprints. Import it anywhere (e.g. tests) without side effects beyond those.
  • Adding an endpoint. Put the handler in the relevant kroft/routes/* blueprint (or a new one registered in routes/__init__.py), and keep any real logic in kroft/services/.
  • Shared state. Mutate the registries in kroft/state.py only while holding the matching lock (jobs_lock, msf_lock, console_lock).
  • Background work. Anything that can take more than a moment should run in a daemon thread and report progress through a state registry, as the existing scan/exploit workers do.

Dependencies

  • Runtime: Flask, SQLAlchemy, python-nmap, pymetasploit3, requests (see requirements.txt / Pipfile).
  • External: the nmap binary, a Metasploit RPC daemon (msfrpcd), and an Ollama server for the AI features.

About

A modern and fun Armitage.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages