What It Does
Point ATLAS at an HTB/CTF machine IP. It runs a six-stage pentest pipeline autonomously โ scans ports, enumerates every service, attacks the web layer, exploits, escalates to root, and generates a Markdown writeup. Human-in-the-loop checkpoints let you review and approve every action, or run fully autonomous with --auto.
Pipeline
Target IP
โ
Recon nmap fast โ deep, NSE vuln scripts, parallel whatweb
โ
Enumerate SMB + FTP + LDAP + SNMP in parallel, hydra brute on found users
โ
Web nikto + gobuster simultaneously per target, vhost ffuf
โ
Exploit searchsploit + LLM plan โ execute โ shell + flag detection
โ
PrivEsc SSH exec: SUID, sudo, caps, cron, kernel, LinPEAS โ root flag
โ
Report Full Markdown writeup, auto-commit to ctf-lab
Elite Features
- Tiered LLM โ Haiku for cheap recon/enum analysis, Sonnet for exploit/privesc planning. Reduces per-run API cost 60โ80% versus Sonnet-only.
- Prompt caching โ Claude system prompts cached across all six agents (~90% cost cut on repeated system context).
- Retry + backoff โ exponential backoff on rate limits and 5xx errors. Cache hit-rate telemetry printed at session end.
- NSE vuln scripts โ free CVE detection: EternalBlue (MS17-010), Shellshock, Heartbleed, MS08-067,
smb-vuln-*. - Hydra brute-force โ auto-fires against SSH/FTP when usernames are enumerated. Top-500 rockyou passwords,
-fstop-on-hit. - SSH-based PrivEsc โ
sshpassruns 18 Linux enum commands (SUID,sudo -l, capabilities, cron, kernel, docker group, bash history). Optional LinPEAS via SSH pipe. - HTB flag auto-capture โ recognizes
HTB{...}and 32-hex legacy flags. Reads/root/root.txtonuid=0detection. - Session portfolio โ
atlas.py --list-sessionsshows every past run with root/user checkmarks.
Parallel Tool Execution
Every stage runs independent tools simultaneously via concurrent.futures.ThreadPoolExecutor:
| Stage | Tools | Sequential | Parallel |
|---|---|---|---|
| Recon | whatweb per port | 4 ports ร 15s = 60s | 15s |
| Enumeration | enum4linux + ftp + ldapsearch + snmpwalk | 4 tools ร 45s = 180s | 45s |
| Web | nikto + gobuster | 2 tools ร 3m = 6m | 3m |
Typical time saving: 60โ70% reduction in tool execution.
Autonomy Dial
--auto-risk controls how much the agent handles itself before pausing:
| Level | Behaviour |
|---|---|
low | Approves scans only. Every exploit still prompts. |
medium (default) | + gobuster/nikto/hydra auto-approve. |
high | + exploits auto-approve. Only critical prompts. |
critical | Full autopilot. |
Even in auto mode, every checkpoint still renders FOUND / PLAN / WHY / LOOK-FOR / COMMAND โ nothing is a black box.
Human-in-the-Loop Checkpoints
Before every action ATLAS shows:
- FOUND โ what was discovered
- PLAN โ what will happen next
- WHY โ attack reasoning
- LOOK FOR โ what indicates success
- COMMAND โ exact command that will run
- RISK โ low/medium/high/critical
Choose: a=approve, s=skip, m=modify command, q=quit.
LLM Providers
| Provider | Backend | Notes |
|---|---|---|
claude | Anthropic API | Prompt caching + auto-tier |
ollama | Local claw-core | On-prem, no data egress |
Auto-tier map: recon/enumeration โ Haiku 4.5, web/exploit/privesc/report โ Sonnet 4.6.
Engineering Details
Prompt caching architecture โ every agent extends BaseAgent with a shared SYSTEM_PROMPT. ClaudeProvider marks the system block with cache_control: ephemeral. Subsequent agent calls read from cache at ~10% the input price.
Thread-safe parallel output โ parallel tool runs suppress per-line streaming (interleaved output is unreadable). Each tool writes its full output to a log file; results are collected after as_completed(). A print lock serialises completion notices.
Checkpoint-then-parallelize pattern โ EnumerationAgent shows per-service checkpoints sequentially (preserving the interactive approval flow), collects approved tasks into a list, then fires them in a single run_parallel() call. No checkpoint is skipped; parallelism only applies to approved execution.
Session resume โ full state (ports, credentials, findings, AgentResult list, LLM metadata) is persisted after each stage. atlas.py --resume --stage privesc picks up exactly where it left off with all context intact.
Shell detection fix โ subprocess captures non-interactive output. The original regex looked for $ and # prompts that never appear post-hoc. Rewritten to match concrete RCE evidence: uid=N(user), /etc/passwd content, uname -a output, Windows version banner, meterpreter tags.
Usage
# Interactive (default) โ pause at every checkpoint
atlas.py 10.10.11.100
# Autonomous below high risk
atlas.py 10.10.11.100 --auto --auto-risk high
# Local claw-core instead of Claude
atlas.py 10.10.11.100 --provider ollama --model hermes3:70b
# Resume from privesc stage
atlas.py 10.10.11.100 --resume --stage privesc
# Portfolio view โ every past run
atlas.py --list-sessions
Output
Each run produces ~/atlas-sessions/<ip>/:
*.txtโ raw tool logs per commandsession.jsonโ full state: ports, creds, findings, agent resultswriteup/<date>-<machine>.mdโ HTB writeup, auto-committed toctf-labatlas_privesc.shโ enum script if no SSH creds (fallback path)
Stack
Python 3.11+ ยท Anthropic SDK (caching enabled) ยท Ollama ยท rich ยท nmap ยท gobuster ยท nikto ยท ffuf ยท enum4linux-ng ยท smbclient ยท ldap-utils ยท snmp ยท hydra ยท sshpass ยท searchsploit