Last reviewed

Autonomous Platform
Advanced
T1595 T1046 T1059

DarkMoon

DarkMoon is an open-source autonomous penetration testing platform. An LLM "brain" plans the assessment, a privacy gateway strips real IPs, hostnames, URLs, and credentials before anything reaches the model, and an MCP gatekeeper runs curated workflows inside an isolated Docker toolbox — so the AI reasons and coordinates but never touches the target directly.

DarkMoon v1.2.0

github.com/ASCIT31/Dark-Moon · GPL-3.0 · Community & Pro editions

50+
Toolbox Utilities
4
Domain Agents
100%
Local Tokenization
3
Report Formats

Architecture Overview

DarkMoon enforces a strict separation of concerns: OpenCode plans, the Privacy Gateway tokenizes, the MCP gatekeeper decides what runs, and the Docker Toolbox executes isolated tools. The model never issues raw commands or sees raw target data.

DarkMoon Autonomous Assessment Flow

Where It Fits in an Engagement

DarkMoon is a breadth-first accelerator, not a replacement for manual depth. Point it at a scoped surface to enumerate technologies, run the relevant agents, and surface candidate findings quickly — then have an analyst reproduce anything it flags. Treat every autonomous result as a lead, not a deliverable.

Good fit

Wide external scopes, bug-bounty recon and triage, repeatable first-pass coverage, and data-sensitive engagements where the local privacy gateway matters.

Poor fit

Business-logic testing, multi-step exploit chains, tightly time-boxed manual work, or any context where autonomous actions are unacceptable.

Before any run

Bake it off against a manual baseline first so you know its false-positive rate and coverage gaps before it ever touches a client.

Privacy Gateway

The defining feature of the v1.2.0 line. Sensitive values are replaced with deterministic placeholders (IP_PRIVATE_001, CRED_SECRET_001) before any request leaves the host, then rehydrated locally inside the toolbox at execution time and re-masked on the way back. This keeps client IPs, hostnames, URLs, and credentials out of the LLM provider entirely.

text
# Privacy gateway — what the model actually sees.
# Real values are deterministically tokenized locally before any LLM call
# and rehydrated only inside the Docker toolbox at execution time.

# Operator target:
TARGET: vpn.acme-corp.com  (10.20.4.8)  creds: svc_scan / Winter2026!

# What leaves the host to the LLM provider:
TARGET: HOST_PUBLIC_001 (IP_PRIVATE_001) creds: CRED_USER_001 / CRED_SECRET_001

# Tool results are re-masked on the way back so the model never
# reasons over raw IPs, hostnames, URLs, or secrets.
# Privacy gateway — what the model actually sees.
# Real values are deterministically tokenized locally before any LLM call
# and rehydrated only inside the Docker toolbox at execution time.

# Operator target:
TARGET: vpn.acme-corp.com  (10.20.4.8)  creds: svc_scan / Winter2026!

# What leaves the host to the LLM provider:
TARGET: HOST_PUBLIC_001 (IP_PRIVATE_001) creds: CRED_USER_001 / CRED_SECRET_001

# Tool results are re-masked on the way back so the model never
# reasons over raw IPs, hostnames, URLs, or secrets.

Verify, don't assume

Privacy claims are only as good as the captured proof. Run a scoped scan with canary hostnames and fake credentials, capture the outbound provider traffic, and confirm the tokenization actually holds before trusting it with client data.

Specialized Agents

DarkMoon dispatches four autonomous domain agents reactively: it discovers technologies, selects the relevant agent, validates findings with evidence, and iterates until attack-surface coverage is exhausted.

pentest-web

Web application vulnerabilities — crawling, fuzzing, injection, CMS, and GraphQL surfaces.

pentest-ad

Windows / Active Directory — enumeration, credential paths, and domain dominance workflows.

pentest-kubernetes

Kubernetes clusters — RBAC, kubelet exposure, and workload attack paths.

pentest-network

Infrastructure protocols — service discovery, fingerprinting, and network-layer checks.

Beneath the four domain agents, the assessment engine dispatches technology-reactive sub-agents as it fingerprints the target: stack-specific agents (PHP, Node.js, Flask, ASP.NET, Spring Boot, Ruby on Rails), a GraphQL agent, a headless-browser agent, and CMS engines (WordPress, Drupal, Joomla, Magento, PrestaShop, Moodle). Coverage therefore adapts to what the target actually runs rather than following a fixed checklist.

MCP Workflows & Toolbox

The AI never runs raw shell. MCP exposes workflows — Python modules that encapsulate a complete task (port scanning, vulnerability scanning, crawling) with structured inputs/outputs and timeout management. Those workflows drive a compiled Docker toolbox of 50+ utilities.

CategoryRepresentative tools
Networknaabu, nmap, zgrab2, snmp utilities
Webhttpx, ffuf, nuclei, katana, sqlmap, wafw00f
Kuberneteskubectl, kubeletctl, kubescape
AD / Infraimpacket (secretsdump, wmiexec, psexec), netexec, bloodhound
CMSwpscan, cmseek, whatweb
WordlistsSecLists, DIRB

Installation

Prerequisites

Docker and Docker Compose, plus access to a capable LLM (a frontier cloud model, or a local model of 32B+ parameters). Smaller local models leave autonomous campaigns stuck in an Unknown state.

1. Clone & Install

bash
# Clone the repository
git clone https://github.com/ASCIT31/Dark-Moon.git
cd Dark-Moon

# Interactive installer: pick LLM provider, pull the toolbox image,
# and build the OpenCode + MCP + Docker stack
./install.sh
# Clone the repository
git clone https://github.com/ASCIT31/Dark-Moon.git
cd Dark-Moon

# Interactive installer: pick LLM provider, pull the toolbox image,
# and build the OpenCode + MCP + Docker stack
./install.sh

2. Configure the LLM Provider

The interactive installer writes a .env. The docs' reference configuration is an Opus-class frontier model; any current top-tier model works, and cloud and local providers are interchangeable.

.env
bash
# .env — provider selection for the OpenCode "AI brain"
# Reference configuration in the docs is an Opus-class frontier model.
OPENCODE_MODEL="anthropic/claude-opus-4-8"     # or the current Opus-class frontier model
OPENROUTER_PROVIDER="anthropic"                # anthropic | openai | groq | mistral | openrouter | local
ANTHROPIC_API_KEY="sk-..."

# Local / self-hosted alternative (Ollama or llama.cpp).
# NOTE: sub-32B models cannot sustain autonomous campaigns.
# OPENROUTER_PROVIDER="local"
# OPENCODE_MODEL="ollama/qwen3-coder:32b"
# .env — provider selection for the OpenCode "AI brain"
# Reference configuration in the docs is an Opus-class frontier model.
OPENCODE_MODEL="anthropic/claude-opus-4-8"     # or the current Opus-class frontier model
OPENROUTER_PROVIDER="anthropic"                # anthropic | openai | groq | mistral | openrouter | local
ANTHROPIC_API_KEY="sk-..."

# Local / self-hosted alternative (Ollama or llama.cpp).
# NOTE: sub-32B models cannot sustain autonomous campaigns.
# OPENROUTER_PROVIDER="local"
# OPENCODE_MODEL="ollama/qwen3-coder:32b"

Frontier cloud (recommended)

The docs cite an Opus-class model as the reference config; use the current Claude Opus / Claude 5-class frontier model, or comparable OpenAI, Groq, Mistral, or OpenRouter models.

Local / self-hosted (32B+)

Opus-class MoE equivalents such as DeepSeek-V3.2, Kimi K2, GLM-4.6, and Qwen3-Coder, or Qwen2.5-Coder-32B, via Ollama or llama.cpp. Sub-32B models cannot sustain autonomous runs.

Model choice is a scope decision

Whatever provider you pick sees the (tokenized) engagement context. Confirm the provider, region, and retention posture are covered by the rules of engagement and the client's data-handling requirements before you run.

3. Run an Authorized Campaign

bash
# Bring the stack up
docker compose up -d

# Launch an authorized assessment against a scoped target
./darkmoon.sh "TARGET: example.com"

# Scope- and safety-bounded run. Note: OUT excludes HOSTS,
# EXCLUDE/FOCUS tune attack CLASSES, and NOISE bounds intensity.
./darkmoon.sh "TARGET: example.com \
  TARGETS: *.example.com \
  OUT: admin.example.com, payments.example.com \
  FOCUS: sqli, ssrf, idor \
  SEVERITY: high \
  NOISE: low \
  SAFE_HARBOR: yes \
  FORMAT: h1"
# Bring the stack up
docker compose up -d

# Launch an authorized assessment against a scoped target
./darkmoon.sh "TARGET: example.com"

# Scope- and safety-bounded run. Note: OUT excludes HOSTS,
# EXCLUDE/FOCUS tune attack CLASSES, and NOISE bounds intensity.
./darkmoon.sh "TARGET: example.com \
  TARGETS: *.example.com \
  OUT: admin.example.com, payments.example.com \
  FOCUS: sqli, ssrf, idor \
  SEVERITY: high \
  NOISE: low \
  SAFE_HARBOR: yes \
  FORMAT: h1"

4. Validate Against a Lab Target First

Before pointing DarkMoon at a client, run it against a deliberately vulnerable target you control. This confirms the Docker stack, GPU/CPU inference, and the privacy gateway all work, and shows you exactly what EXPLOITED vs Confirmed output looks like on a known-vulnerable app.

bash
# Stand up a deliberately vulnerable target you control
docker run -d -p 3000:3000 bkimminich/juice-shop   # OWASP Juice Shop

# Point a tight, low-noise campaign at it
./darkmoon.sh "TARGET: http://localhost:3000 \
  TARGETS: http://localhost:3000 \
  NOISE: low \
  SAFE_HARBOR: yes"

# In a second shell, stream what the agents are actually doing
./darkmoon.sh --log <session_id>

# Confirm output landed and inspect the evidence
ls ./reports/
# Stand up a deliberately vulnerable target you control
docker run -d -p 3000:3000 bkimminich/juice-shop   # OWASP Juice Shop

# Point a tight, low-noise campaign at it
./darkmoon.sh "TARGET: http://localhost:3000 \
  TARGETS: http://localhost:3000 \
  NOISE: low \
  SAFE_HARBOR: yes"

# In a second shell, stream what the agents are actually doing
./darkmoon.sh --log <session_id>

# Confirm output landed and inspect the evidence
ls ./reports/

While it runs, capture the outbound LLM traffic and confirm your canary hostnames and credentials were tokenized before anything left the host — that is the only real proof the privacy gateway holds.

Community vs Pro

CapabilityCommunityPro
Autonomous multi-agent campaignsYesYes
Privacy gateway (local tokenization)YesYes
50+ tool Docker toolboxYesYes
Report formatsStandard · HackerOne · Bugcrowd+ Signed PDF
Web UI + scheduled campaignsCLI onlyWeb UI at :80, scheduling
CI/CD headless modeGitHub Actions · GitLab CI
SSO (Authelia / OIDC)Yes
Vulnerability evolution trackingYes
Runtime hardening + sealed stateYes

Pro activation

bash
# Pro Edition: activate with a licence key
sudo ./install.sh LICENSE-KEY

# Add or rotate LLM providers on a live stack
./darkmoon.sh --connect

# Web UI (change the default admin/admin credentials immediately)
# http://localhost:80
# Pro Edition: activate with a licence key
sudo ./install.sh LICENSE-KEY

# Add or rotate LLM providers on a live stack
./darkmoon.sh --connect

# Web UI (change the default admin/admin credentials immediately)
# http://localhost:80

Pro runtime hardening

Licence + hardware fingerprinting

Binds the Pro stack to authorized hosts.

Locked-down runtime

Read-only filesystem, no-new-privileges, all Linux capabilities dropped.

Integrity verification

Runtime SHA-256 checks of the compose policy and toolbox binaries.

Sealed state

AES-GCM encrypted campaign state at rest.

Tamper response

Debugger detection, fork-bomb limiting, and a compromise marker that blocks restart after tampering.

Scope & Safety Flags

Campaign behavior is controlled through directives passed in the run prompt. Scope is defined with TARGETS (in-scope) and OUT (out-of-scope); EXCLUDE and FOCUS tune attack classes, not hosts. Set these deliberately — defaults are permissive enough to wander outside a tight engagement.

EXCLUDE does not exclude hosts

A common and dangerous mistake: EXCLUDE skips attack classes (e.g. dom-xss, clickjacking), not targets. To keep the agents off a host or range, use OUT. Confirm your exclusions with an out-of-scope canary in a lab before any client run.
FlagPurposeExample
PROGRAMProgram / engagement name used in the report headerPROGRAM: Acme BB 2026
TARGETSAdditional in-scope assets — domains, wildcards, APIsTARGETS: *.acme.com, API:https://api.acme.com
OUTOut-of-scope hosts, paths, or ranges the agents must never touchOUT: payments.acme.com, 10.0.0.0/8
EXCLUDEAttack classes to skip — not hosts (use OUT for hosts)EXCLUDE: dom-xss, clickjacking, CWE-352
FOCUSPrioritize specific attack classesFOCUS: sqli, rce, ssrf, idor
CREDSAuthorized test credentials (tokenized before any LLM call)CREDS: admin:admin@test.com:Pass1@http://t/login
TOKENPre-auth token / session material for authenticated testingTOKEN: bearer:eyJhbG...@api.acme.com
NOISEDiscovery aggressivenessNOISE: stealth | low | moderate
SEVERITYMaximum severity the run is allowed to escalate toSEVERITY: critical | high | medium | low
FORMATReport output formatFORMAT: standard | h1 | bugcrowd | custom
RULESFree-text engagement rules the agents must followRULES: POC only; no real data
SAFE_HARBORDeclare safe-harbor status for conservative behaviorSAFE_HARBOR: yes | no

Usage example

Establish authorization in the run

Encode scope directly into the campaign: program context, focus surface, exclusions, and a conservative safety posture.
text
TARGET: example.com
PROGRAM: acme-public-bbp
TARGETS: *.example.com
OUT: status.example.com, blog.example.com
FOCUS: idor, ssrf, sqli
SAFE_HARBOR: yes
SEVERITY: high

# I have written authorization to test *.example.com under the Acme
# public bug bounty program. Run an authorized assessment, validate
# findings with evidence, and produce a HackerOne-format report.
TARGET: example.com
PROGRAM: acme-public-bbp
TARGETS: *.example.com
OUT: status.example.com, blog.example.com
FOCUS: idor, ssrf, sqli
SAFE_HARBOR: yes
SEVERITY: high

# I have written authorization to test *.example.com under the Acme
# public bug bounty program. Run an authorized assessment, validate
# findings with evidence, and produce a HackerOne-format report.

Monitoring, Output & Control

Campaigns run unattended, so know how to watch and bound them before you launch.

Live session log

./darkmoon.sh --log <session_id> streams every command the MCP server executes, so you can watch the agents in real time and catch out-of-scope behavior early.

Reports & artifacts

Findings, evidence, and the attack-surface graph are written to ./reports/. Pull raw request/response evidence from there straight into your own deliverable.

Stopping a run

There is no built-in pause or kill — a campaign runs until coverage is judged sufficient. To abort, tear the stack down with docker compose down.

No clean kill switch — bound runs up front

Because there is no graceful abort, treat every launch as committed. Scope tightly with TARGETS/OUT, start unfamiliar targets at NOISE: stealth or low, cap escalation with SEVERITY, and validate scope enforcement in a lab before a client run. Frontier models running autonomously across a full surface can also run long and rack up token cost — bound the surface with FOCUS and SEVERITY rather than letting a run range freely.

Evidence & Reporting

Findings are reported only with supporting HTTP requests, payloads, and responses, and are triaged into two states so a human knows what still needs review:

EXPLOITED

Reproducible proof attached — the platform demonstrated the issue end to end.

Confirmed (review needed)

Strong signal but requires analyst validation before it goes in the report.

Reports export to standard, HackerOne, and Bugcrowd formats (signed PDF on Pro), alongside an interactive attack-surface graph and, on Pro, vulnerability-evolution tracking across campaigns.

Pre-Flight Checklist

Clear every item before pointing DarkMoon at anything you do not own.

  • Written authorization that explicitly covers autonomous, tool-driven testing of the exact scope
  • Scope encoded in the run: TARGETS for in-scope assets, OUT for every exclusion (not EXCLUDE)
  • A dedicated, isolated engagement host or VM on an RoE-approved network path
  • LLM provider, region, and retention cleared against the client's data-handling rules
  • Privacy gateway verified against captured outbound traffic using canary values
  • Pro Web UI default admin/admin credentials changed before exposure
  • Scope-enforcement dry run in a lab: an out-of-scope canary confirmed blocked
  • Emergency stop understood — docker compose down; there is no graceful abort

Troubleshooting

GPU driver error: could not select device driver "nvidia"

On WSL, run wsl --update then wsl --shutdown and restart Windows. On native Linux, reinstall nvidia-container-toolkit with the official GPG keys. No GPU? CPU fallback works via pocl-opencl-icd with no extra configuration.

Campaign stuck in the "Unknown" state

The model is too small. 7B/13B models cannot sustain the autonomous agent loop — switch to a frontier cloud model or a 32B+ local model.

Pasting into the prompt yields nothing

An OSC 52 clipboard limitation in your terminal, not DarkMoon. Use kitty, WezTerm, Alacritty, or Windows Terminal.

Security Considerations

  • Run DarkMoon from an isolated host or VM dedicated to the engagement, on a network path approved by the RoE.
  • Change the Pro Web UI's default admin/admin credentials before exposing it to anything.
  • Set EXCLUDE, SAFE_HARBOR, and target allowlists explicitly — autonomous agents will otherwise probe the full discovered surface.
  • Verify the privacy gateway against captured traffic before trusting it with real client IPs, hostnames, or credentials.
  • Keep a human in the loop: treat Confirmed findings as hypotheses and reproduce them before reporting.

DarkMoon vs HexStrike AI

Both are MCP-based agentic pentest orchestrators. DarkMoon leans on a local privacy gateway, a compiled Docker toolbox, four focused domain agents, and a Community/Pro split. HexStrike ships a much larger tool/agent surface (150+ tools, 12+ agents) exposed straight to MCP clients. See the platform comparison for a side-by-side.

Operator Tooling

Operator Playbook

Assess DarkMoon as an MCP-gated autonomous pentest orchestrator: validate its privacy gateway, execution controls, and evidence quality before trusting it on an authorized engagement.

Authorized use only

Offensive Focus

  • Prove the privacy gateway actually tokenizes IPs, hostnames, URLs, and credentials before any LLM call.
  • Confirm the MCP gatekeeper and Docker toolbox enforce which workflows run, with no raw shell passthrough.
  • Use the autonomous agent output as evidence-backed hypotheses that a human validates, not as final findings.

Evidence To Capture

  • Written scope and allowed test classes
  • Timestamped prompts, retrieved context, tool calls, and response artifacts
  • Request IDs, model/provider/version, policy decisions, and tenant or user role
  • Screenshots or exported logs that reproduce the finding without exposing client secrets

Offensive Test Cases

Privacy gateway leak test

Objective
Verify no real IP, hostname, URL, or credential leaves the local boundary in an LLM request.
Authorized setup
Run a scoped scan against a lab target with canary hostnames and fake credentials, capturing outbound provider traffic.
Evidence
Outbound payload capture, tokenized placeholders (e.g. IP_PRIVATE_001), and local rehydration logs.

Autonomy boundary review

Objective
Confirm the MCP gatekeeper blocks tools and targets outside the approved scope during an autonomous campaign.
Authorized setup
Configure a restricted target allowlist and SAFE_HARBOR/EXCLUDE flags on a disposable range.
Evidence
Agent plan, workflow calls, denied actions, and the final structured report with per-finding proof.

Common Findings

  • Privacy-gateway tokenization is assumed rather than verified against captured outbound traffic.
  • Autonomous campaigns run with default scope, so agents probe beyond the approved target set.
  • Evidence-backed findings are accepted without human reproduction of the supporting request/response.

Lab Ideas

  • Run DarkMoon against a vulnerable-by-design range and compare its report to a manual baseline.
  • Capture and inspect the outbound LLM traffic to confirm no sensitive values leave the host.
  • Test EXCLUDE, SAFE_HARBOR, and target allowlist controls to confirm scope enforcement.