Skip to content

Latest commit

 

History

168 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NetAttackAI

Python Status License Models MCP WebUI Skills Swarm Tests Models Transport Context Audit web

An AI-driven, local-first penetration testing & bug bounty research agent. All in One Web Interface!

Plan, reconnoiter, exploit, and report end to end against targets you own or are explicitly authorized to assess. An autonomous operator that thinks in kill-chains, not checklists: it scouts the surface, picks the attack, runs it, proves the outcome with evidence, and writes the report. Powered by Ollama LLMs, the Model Context Protocol, and a 140-skill advisory knowledge base. Lab-only, target-locked, fully audited.


Warning

Authorized use only. Run NetAttackAI solely against networks and systems you own or have explicit written authorization to test, on a throwaway operator box.

Attack mode ships as full_access: every action is auto-approved with no command-content or scope inspection. The operator-box filesystem is unrestricted (write_python_file / read_workspace_file reach any path). The single remaining attack-path safety is the target-IP allowlist lock, a destination guard that refuses off-target hosts. It is not authorization proof, not a sandbox, and a statically-constructed or DNS-resolved destination may evade it. Recon keeps its full scope-gated safety model.

See Safety model and docs/safety-model.md.


What it is

A coupled assessment engine, not an nmap wrapper with a chatbot on top:

  • Assessment controller (main.py / app.py): opens an MCP exploit session, dispatches tool calls, streams live events to a CLI or browser.
  • Defensive MCP server (mcp_server.py): scope-gated Nmap, sanitized vulnerability search, NVD CVE lookup. Read-only by design.
  • Permissive exploit MCP server (mcp_exploit_server.py, port 8001): terminal, Python write/run, searchsploit, Metasploit, msfvenom, impacket lateral movement, credential dumping, kerberoasting, web scanning, hash cracking. Gated by the target-IP allowlist lock at the tool layer.
  • Multi-agent swarm (tools/swarm/): 6 specialist agents (recon, vuln, exploit, post-exploit, critic, reflection) with a shared blackboard.
  • Autonomous attack orchestrator (tools/autonomous_orchestrator.py): persistent multi-phase campaigns with adaptive aggression, vuln chaining, and auto-retry.
  • Runtime skills system: 140 advisory SKILL.md files indexed, deterministically + semantically selected, injected into LLM context per phase. Advisory only, never grants execution authority.
  • Bundled WebUI (React + Vite + TypeScript) served by a loopback-only REST + WebSocket API daemon.

For the full architecture, Flow A/B split, and module map, see docs/architecture.md and docs/module-guide.md.

Highlights

  • Cloud-first, local-capable. Default model path is Ollama Cloud (glm-5.2:cloud, 976K context). Swap ollama.host to a local daemon and the same code path runs against it. Embeddings stay local via nomic-embed-text.
  • Multi-model war room. Ask Kimi K2.6, DeepSeek V4 Pro/Flash, GLM-5.2, and Minimax M3 for advisory ideas mid-run. Peers have no tool schemas and cannot execute commands.
  • 140-skill advisory brain. Each SKILL.md carries NIST CSF + MITRE ATT&CK metadata. Selected deterministically + semantically, re-selected mid-run as new services/CVEs surface, with cross-mission Bayesian feedback.
  • Hypothesis-driven outcome judgment. Every executed check produces structured observations; OutcomeJudge evaluates them against task criteria and persists a terminal confirmed / refuted / exhausted verdict. Execution success ≠ evidential success.
  • Tamper-evident audit chain. Every target-touching action lands in exploit_workspace/<ip>/exploit_audit.jsonl with SHA256 of generated code. Chain validity is verified and surfaced in the WebUI.
  • Target-aware OPSEC. Pacing, UA rotation, DNS-over-HTTPS, and quiet-command hints auto-disable for private/local IPs and engage for public-routable targets. Advisory-only, never a gate.
  • Domain targeting. Pass --target example.com; the agent resolves it, expands subdomains (crt.sh + DNS bruteforce + subfinder/amass), and auto-authorizes each discovered host through the allowlist lock.
  • Long-session mode. Opt-in multi-hour runs send the model's real context window to Ollama, bound each LLM call with an httpx timeout, and checkpoint compacted state for crash recovery.
  • Eval harness. Benchmark against target labs with JSON/Markdown/HTML reports under reports/eval/<run_id>/.
  • 179-test suite, all mocked. No live Nmap, no live network: every test mocks subprocess/network and runs offline.

Quick start

1. Prerequisites

  • Python 3.11+ (the --doctor check rejects 3.10)
  • nmap on PATH (or set nmap.path in config.yaml)
  • An Ollama endpoint: cloud is the default (https://api.ollama.com, needs OLLAMA_API_KEY) or a local daemon (ollama.host: http://localhost:11434)
  • Optional, Linux full arsenal: Metasploit, searchsploit, impacket, tmux
  • For the WebUI: Node.js + npm (only on first --web run)
  • ChatGPT provider (optional): bun ≥ 1.3.11 to run the vendored oauth/ proxy from source (only when models.provider: chatgpt). A local Ollama is still required for embeddings even under the ChatGPT provider. See docs/providers.md.

2. Install

# Windows PowerShell (this repo's primary dev platform)
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
# Linux / macOS
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
./scripts/setup-linux.sh        # one-shot bootstrap: venv + deps + doctor

Linux nmap -O/-sS need root: set nmap.sudo: true (uses sudo -n) or run as root; otherwise nmap.priv_fallback (default true) auto-downgrades.

ChatGPT provider one-time setup (only if you'll set models.provider: chatgpt):

cd openai-oauth && bun install && cd ..   # bun@1.3.11; makes ./src/cli.ts runnable

install.bat / install.sh / scripts/setup-linux.sh run this best-effort when bun is on PATH; it never aborts the install if bun is missing, since ChatGPT is opt-in. No global Codex CLI install is required.

3. Configure API keys (before --doctor)

The default cloud path requires OLLAMA_API_KEY or the doctor's Ollama reachability check will 401. Keys are read from process environment variables or secr.json; there is no .env auto-load. Set them with:

python main.py --setup-api-keys      # prompts + writes secr.json (gitignored)
Var Purpose
OLLAMA_API_KEY Required for the default Ollama Cloud path
NVD_API_KEY Raises NVD CVE lookup rate limit
GITHUB_TOKEN Raises cve_to_poc GitHub Search API limit 60→5000/hr
SERPAPI_API_KEY Optional fallback web research provider
NETATTACKAI_API_TOKEN Override the auto-generated WebUI bearer token

.env.example documents the same vars; copy it to .env for your own shell-load workflow, but the app itself does not read .env.

ChatGPT provider (opt-in, models.provider: chatgpt) does not use an env API key. It authenticates via a browser "Sign in with ChatGPT" OAuth flow whose tokens live in ~/.codex/auth.json (managed by the vendored oauth/ proxy). They are never copied into config.yaml or logged. Run python main.py → choose ChatGPTSign in with ChatGPT, or see docs/providers.md.

4. Verify

python main.py --doctor          # env check (Python/nmap/Ollama/models/config; +ChatGPT when provider=chatgpt)
python main.py --self-test       # safe localhost smoke test
python main.py                   # WebUI daemon (default no-args; opens browser)
python main.py --menu            # terminal interactive menu (legacy)

--doctor exits 0 when all checks pass. Cloud models are verified by running a 1-token generation (the programmatic ollama run); local models report a ollama pull <spec> hint if missing. When models.provider: chatgpt, the doctor adds a ChatGPT block: openai-oauth source found, runtime (bun/node) on PATH, OAuth login present, proxy running, and /v1/models reachable. It never displays token contents.

Choose an interface

Interface Start Notes
WebUI python main.py Default. Builds webui/dist/ on first run (needs Node/npm), opens http://127.0.0.1:8765
CLI menu python main.py --menu Guided questionary flow; no extra deps
CLI direct python main.py --target <ip> --mode recon|attack Flags below
API only python main.py --demon Daemon without the SPA

WebUI: bearer token auto-generated into .webui_secret_key (gitignored) or set NETATTACKAI_API_TOKEN. Loopback-only, one active run at a time (HTTP 409 on conflict). Docs at http://127.0.0.1:8765/docs. Full SPA reference in docs/webui.md and docs/api.md.

Choose an AI provider

The default is Ollama (cloud or local daemon). To use ChatGPT instead, pick it in the interactive menu (python main.py --menuSelect AI providerChatGPTSign in with ChatGPT) or the WebUI's System page, or set models.provider: chatgpt in config.yaml. Both providers share the same ModelClient/ModelRouter surface, so every run path (CLI, WebUI, swarm, autonomous) works unchanged; embeddings always stay on Ollama. Full setup, proxy lifecycle, and security notes in docs/providers.md.

CLI showcase

# Recon against an allowed target (propose-only, safe)
python main.py --target 10.0.0.50 --mode recon --recon-first

# Attack with a preset goal
python main.py --target 10.0.0.50 --mode attack --goal backdoor

# Full-power swarm run
python main.py --target 10.0.0.50 --mode attack --swarm --critic \
    --reflection --adaptive-exploits

# Multi-hour attack mode (raises context window, budgets, checkpoints)
python main.py --target 10.0.0.50 --mode attack --long-session

# Domain targeting — resolve, expand subdomains, attack the surface
python main.py --target example.com --mode attack

# Engine advisory MCP server (read-only surface for foreign AI assistants)
python mcp_engine_server.py

Notable flags: --model <alias>, --mcp-transport stdio|http, --parallel-swarm, --multi-model-consult, --ultrathink, --skills on|off|hints|lookup, --skills-list, --eval, --ctf (CTF autopilot with goal-completion detection), --resume <run_id>, --yes (skip confirm gate). Run python main.py --help for the full list.

Legacy research CLI (Flow B, SQLite-backed)

python cli.py init-mission --config mission.yaml
python cli.py next-task
python cli.py run-task T-00001
python cli.py list-findings
python cli.py generate-report F-00001
python cli.py status

Flow B is the database-driven, scope-gated research loop. See docs/runtime-flows.md.

Safety model

This is a lab-only build. The attack path is unrestricted but target-locked.

Context Effective permission
--mode recon Always read_only: gathers and proposes, no offensive execution
--mode attack Uses exploit.permission from config.yaml
Shipped attack default full_access: auto-approves every action, no content/scope inspection
Safer attack posture approve_only: prints an approval banner per action

The one attack-mode safety: the target-IP allowlist lock, enforced at the MCP tool layer (tools/mcp_shared._allowed_target_list + tools/mcp_tools/terminal._target_lock_block), not in policy. It unions EXPLOIT_TARGET (the runtime --target) with exploit.allowed_targets, plus EXPLOIT_TARGET_IP / EXPLOIT_TARGET_DOMAIN / EXPLOIT_DISCOVERED_TARGETS for domain targeting. Every destination in every command (URL authorities, /dev/tcp hosts, LHOST/RHOST, scanner verbs, bare IPs, hostnames) is extracted and refused if not in the allowlist. Supports domains + *.wildcard + CIDR. Interactive target entry persists to exploit.allowed_targets; domain enumeration auto-authorizes discovered hosts; callback/C2 hosts must be added explicitly.

What the lock is not: authorization proof, a sandbox, or a guarantee that a dynamically-constructed or DNS-resolved destination is caught. It is a destination guard. Recon keeps its full safety (post-session SafetyReviewer, READ_ONLY propose-only path, goal-menu SAFE/GATED narrowing, defensive scope-gated mcp_server.py).

Operational guards that remain regardless of mode: command timeouts (300s terminal / 300s python / 600s msf), full JSONL audit trail (exploit_workspace/<ip>/exploit_audit.jsonl) with SHA256 of generated code, OS-aware tooling (Windows attacker = Python-only; Linux = full Kali arsenal).

OPSEC is advisory-only, never a gate. Pacing, UA rotation, DoH, and quiet-command hints auto-disable for private/local target IPs and engage for public-routable targets. is_quiet_blocked / noise_budget stay dormant.

Full layered model: docs/safety-model.md.

Configuration

All runtime behavior lives in config.yaml. Key sections:

Key Purpose
ollama host, model (glm-5.2:cloud), embed_host (local embeddings)
models provider (ollama default | chatgpt), registry (kimi/deepseek/deepseek_flash/glm/minimax), default_alias
chatgpt opt-in ChatGPT provider: base_url (loopback 127.0.0.1:10531), auto_start, local_repo, runtime, default_model, context_window, discovery/login/proxy timeouts
exploit permission, attack_mode, timeouts, allowed_targets, require_explicit_allowlist, AD/Kerberos suite, MSF recipes, listeners
opsec target-aware OPSEC (pacing, UA rotation, DoH, local_targets_off)
cve_lookup NVD CVE lookup: rate limit, circuit breaker, epss_enabled/kev_enabled (EPSS + CISA KEV enrichment, lab default true, live out of the box), kev_cache_ttl_seconds/kev_cache_path, github.token_env (GITHUB_TOKEN, shared with threat_intel + github_dorks)
threat_intel continuous OSV.dev + GitHub Security Advisories + CISA KEV feed ingestion (search_threat_intel MCP tool). Advisory-only, never touches the target. enabled (lab default true), cache_dir/cache_ttl_seconds, sources (osv/ghsa/kev/exploitdb_rss), max_results, github_token_env. Reuses cve_lookup's KEV catalog. GHSA degrades to osv+kev when GITHUB_TOKEN is unset
swarm agents, parallel_enabled, per_phase_concurrency, negotiation_rounds (bounded critic↔exploit loop; 0 = legacy one-shot, 2 = lab default)
witness advisory audit-stream watcher (enabled, log_path, poll_interval_seconds, escalate_to_event_broker): flags anomalies mid-run (allowlist breach, PoC escape, perm escalation, prompt injection, DoS drift), never blocks; lab default ON for telemetry
autonomous persistence phase, checkpoint, adaptive_replan, max_cycles
orchestrator semantic_memory (cross-mission lesson consumer for the autonomous orchestrator; lab default true, matching memory.semantic_enabled)
recon extended enumerators, UDP top-ports, shodan_api_key (wired into the shodan_recon plugin: passive OSINT, advisory-only), domain resolution
skills selection, re-selection, feedback, semantic matching, maybe_enabled (gates the skills/maybe/ opt-in pack; default false)
outcome_judgment evidence-grounded verdicts (flow_a wires OutcomeJudge into Flow A; peer_review enables cross-model outcome grading)
poc_verification self-healing PoC verification: cve_to_exploit_synth syntax-checks its PoC inline; verify_poc MCP tool compile-tests in isolated Docker (--network=none --read-only --memory=256m)
replay_simulator pre-commit attack-plan critique (replay_simulate MCP tool: LLM critiques its own plan against saved ReconAssessment, with rule-based fallback)
api WebUI daemon host/port/token/origins, graph_route (attack-path DAG), max_concurrent_runs (D3: N concurrent runs for wide-scope assessments; lab default 3; set 1 for legacy single-run 409), multi_operator (D4: user accounts + annotations; lab default true, loopback-only)
ics D8: allow_write (lab default true: operator runs against owned PLCs; physical-damage risk). Write-side ICS modules are DESTRUCTIVE. Dual-gated: @require_allowlist on run_attack_module AND ics.allow_write: true. Set false for read-only ICS enum
long_session multi-hour mode, request timeout, checkpoint
plugins out-of-tree plugin enable/disable, search paths, entry points
webhook_notify outbound Slack/Discord run-status notifications (url, event filter, retry/backoff)
mitre MITRE ATT&CK Navigator export (technique map, output dir, skill tags)
ticketing remediation ticket generation (Jira/GitHub, provider, base_url, token env)

Mission scope (allowed/disallowed assets, forbidden actions, risk profiles) for Flow B lives in mission.yaml. Three risk profiles: low_noise_non_destructive, standard_authorized, high_authorized_testing.

Hard-blocked actions regardless of config: denial_of_service, destructive_exploit, social_engineering, physical_attack, malware, credential_theft (see scope_gate.py:_HARD_FORBIDDEN_ACTIONS).

Testing

python -m pytest tests/ -v                              # full suite (179 files)
python -m pytest tests/test_scope_gate.py -v            # single file
python -m pytest tests/test_recon_pipeline.py::TestClass::test_method  # one test
python -m pytest tests/ -v -k "scope"                   # by keyword
python -m pytest --cov=tools --cov=main.py --cov=cli.py # coverage

All tests mock subprocess/network: no live Nmap, no live network. pytest config: asyncio_mode = "auto", testpaths = ["tests"].

CI (GitHub Actions)

CI runs on every push and pull request (concurrency-cancelled, no secrets required, nothing touches the network):

  • Python tests on Python 3.11, 3.12, and 3.13 — the full mocked/offline suite (python -m pytest tests/ -v).
  • Coverage on Python 3.12: terminal report + coverage.xml artifact.
  • Ruff on the currently passing scope (safety core + intelligence + providers): app.py, scope_gate.py, tools/safety_reviewer.py, tools/validation_utils.py, tools/intelligence, tools/providers. Repository-wide ruff check . still reports ~1800 pre-existing violations (mostly import sorting) that are out of scope here.
  • mypy on the currently passing typed core (--follow-imports=skip): summarizer.py, planner.py, observer.py, target_graph.py, outcome_judge.py, db.py, mcp_exploit_server.py, tools/mcp_shared.py. The rest of the codebase is not yet type-clean.
  • Package build: python -m build + python -m twine check dist/*.
  • WebUI: npm ci, npm run build (tsc + vite), npm run test (vitest).

Security automation: CodeQL (Python + JavaScript/TypeScript) on push/PR/weekly, GitHub dependency review on pull requests, and Dependabot for pip / GitHub Actions / npm (weekly, grouped).

Before opening a PR, run the same checks locally:

python -m pip install -e ".[dev]"
python -m pytest tests/ -v
ruff check app.py scope_gate.py tools/safety_reviewer.py tools/validation_utils.py tools/intelligence tools/providers
mypy --follow-imports=skip summarizer.py planner.py observer.py target_graph.py outcome_judge.py db.py mcp_exploit_server.py tools/mcp_shared.py
cd webui && npm ci && npm run build && npm run test

and verify README flags/config still match reality.

Plugins

Out-of-tree extensions managed by tools/plugins.py (pure stdlib). A plugin can contribute an attack module, MCP tools, a skills directory, and a config section. Plugins are disabled by default; enable via config plugins.enabled. A reference plugin lives at plugins/example_recon_report/. See docs/plugin-development.md.

Shipped plugins (lab build: enabled by default; enabling requires both plugins.enabled and the API key/token in config.yaml):

  • shodan_recon: passive Shodan OSINT (shodan_host_lookup, shodan_search MCP tools). Advisory-only, never touches the target. Requires recon.shodan_api_key; MCP tool returns BLOCKED: when unset. Pure stdlib (urllib).
  • github_dorks: authorized-target code-leak discovery (search_github_dorks MCP tool). Runs curated dorks against a target org's public GitHub repos. Requires GITHUB_TOKEN (cve_lookup.github.token_env); MCP tool returns BLOCKED: when unset. Advisory-only.

Documentation

Engineering docs in docs/:

Operators

Integrators

Contributors

Contributing

  1. Read AGENTS.md first: it lists the non-obvious rules you will otherwise break.
  2. Run python main.py --doctor and python main.py --self-test after safety-sensitive changes.
  3. Run the CI checks locally before opening a PR — see CI (GitHub Actions) above.
  4. Do not edit Flow B safety files (scope_gate.py, safety_reviewer.py, Flow B's agent_loop.py/tool_router.py/risk_controller.py/mission.py/ db.py): recon safety depends on them.
  5. New exploit MCP tools must be registered twice: @audit_tool in tools/mcp_tools/<family>.py, then added to the tool list in mcp_exploit_server.py. Target-touching tools require a target IP and the @require_allowlist() gate.
  6. When adding a CLI flag, MCP tool, or config key, update the relevant README section.

License

NetAttackAI, Copyright (c) 2026 NetAttackAI contributors.

Licensed under the GNU General Public License v3.0 only. See LICENSE for the full text.

About

Autonomous Offensive Security Agent for Red Team Operations

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages