aegis-pentest 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aegis_pentest-0.1.0/.gitignore +17 -0
- aegis_pentest-0.1.0/.python-version +1 -0
- aegis_pentest-0.1.0/PKG-INFO +347 -0
- aegis_pentest-0.1.0/README.md +324 -0
- aegis_pentest-0.1.0/pyproject.toml +46 -0
- aegis_pentest-0.1.0/scripts/PKGBUILD +63 -0
- aegis_pentest-0.1.0/src/aegis/__init__.py +1 -0
- aegis_pentest-0.1.0/src/aegis/cli/__init__.py +0 -0
- aegis_pentest-0.1.0/src/aegis/cli/console.py +4 -0
- aegis_pentest-0.1.0/src/aegis/cli/env.py +232 -0
- aegis_pentest-0.1.0/src/aegis/cli/kb.py +139 -0
- aegis_pentest-0.1.0/src/aegis/cli/main.py +465 -0
- aegis_pentest-0.1.0/src/aegis/db/__init__.py +4 -0
- aegis_pentest-0.1.0/src/aegis/db/engine.py +25 -0
- aegis_pentest-0.1.0/src/aegis/db/findings_db.py +181 -0
- aegis_pentest-0.1.0/src/aegis/db/models.py +114 -0
- aegis_pentest-0.1.0/src/aegis/env/__init__.py +0 -0
- aegis_pentest-0.1.0/src/aegis/env/models.py +89 -0
- aegis_pentest-0.1.0/src/aegis/env/profiler.py +375 -0
- aegis_pentest-0.1.0/src/aegis/kb/__init__.py +2 -0
- aegis_pentest-0.1.0/src/aegis/kb/database.py +179 -0
- aegis_pentest-0.1.0/src/aegis/kb/ghsa.py +105 -0
- aegis_pentest-0.1.0/src/aegis/kb/knowledge_base.py +88 -0
- aegis_pentest-0.1.0/src/aegis/kb/models.py +61 -0
- aegis_pentest-0.1.0/src/aegis/kb/nuclei_index.py +156 -0
- aegis_pentest-0.1.0/src/aegis/kb/nvd.py +178 -0
- aegis_pentest-0.1.0/src/aegis/llm/__init__.py +3 -0
- aegis_pentest-0.1.0/src/aegis/llm/anthropic_backend.py +111 -0
- aegis_pentest-0.1.0/src/aegis/llm/base.py +38 -0
- aegis_pentest-0.1.0/src/aegis/llm/claude_code_backend.py +121 -0
- aegis_pentest-0.1.0/src/aegis/llm/factory.py +80 -0
- aegis_pentest-0.1.0/src/aegis/llm/models.py +40 -0
- aegis_pentest-0.1.0/src/aegis/llm/ollama_backend.py +58 -0
- aegis_pentest-0.1.0/src/aegis/logging_config.py +38 -0
- aegis_pentest-0.1.0/src/aegis/mcp_server/__init__.py +3 -0
- aegis_pentest-0.1.0/src/aegis/mcp_server/__main__.py +4 -0
- aegis_pentest-0.1.0/src/aegis/mcp_server/server.py +338 -0
- aegis_pentest-0.1.0/src/aegis/methodology/__init__.py +4 -0
- aegis_pentest-0.1.0/src/aegis/methodology/engine.py +154 -0
- aegis_pentest-0.1.0/src/aegis/methodology/phases.py +160 -0
- aegis_pentest-0.1.0/src/aegis/methodology/wstg.yaml +176 -0
- aegis_pentest-0.1.0/src/aegis/orchestrator/__init__.py +2 -0
- aegis_pentest-0.1.0/src/aegis/orchestrator/loop.py +359 -0
- aegis_pentest-0.1.0/src/aegis/orchestrator/planner.py +101 -0
- aegis_pentest-0.1.0/src/aegis/report/__init__.py +3 -0
- aegis_pentest-0.1.0/src/aegis/report/renderer.py +170 -0
- aegis_pentest-0.1.0/src/aegis/scope/__init__.py +0 -0
- aegis_pentest-0.1.0/src/aegis/scope/guard.py +73 -0
- aegis_pentest-0.1.0/src/aegis/scope/models.py +32 -0
- aegis_pentest-0.1.0/src/aegis/tools/__init__.py +11 -0
- aegis_pentest-0.1.0/src/aegis/tools/base.py +89 -0
- aegis_pentest-0.1.0/src/aegis/tools/catalog.py +71 -0
- aegis_pentest-0.1.0/src/aegis/tools/executor.py +173 -0
- aegis_pentest-0.1.0/src/aegis/tools/models.py +78 -0
- aegis_pentest-0.1.0/src/aegis/tools/parsers/__init__.py +0 -0
- aegis_pentest-0.1.0/src/aegis/tools/parsers/ffuf.py +26 -0
- aegis_pentest-0.1.0/src/aegis/tools/parsers/httpx.py +40 -0
- aegis_pentest-0.1.0/src/aegis/tools/parsers/nmap.py +38 -0
- aegis_pentest-0.1.0/src/aegis/tools/parsers/nuclei.py +37 -0
- aegis_pentest-0.1.0/src/aegis/tools/parsers/subfinder.py +17 -0
- aegis_pentest-0.1.0/src/aegis/tools/parsers/whatweb.py +24 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/__init__.py +0 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/ffuf.py +51 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/gobuster.py +55 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/httpx_tool.py +40 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/katana.py +50 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/nmap.py +48 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/nuclei.py +55 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/subfinder.py +32 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/testssl.py +56 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/whatweb.py +33 -0
- aegis_pentest-0.1.0/src/aegis/tools/wrappers/wpscan.py +59 -0
- aegis_pentest-0.1.0/src/aegis/verify/__init__.py +3 -0
- aegis_pentest-0.1.0/src/aegis/verify/probes.py +312 -0
- aegis_pentest-0.1.0/templates/report/report.html.j2 +200 -0
- aegis_pentest-0.1.0/templates/report/report.md.j2 +120 -0
- aegis_pentest-0.1.0/tests/__init__.py +0 -0
- aegis_pentest-0.1.0/tests/conftest.py +44 -0
- aegis_pentest-0.1.0/tests/fixtures/.gitkeep +0 -0
- aegis_pentest-0.1.0/tests/test_probes.py +101 -0
- aegis_pentest-0.1.0/tests/test_report.py +55 -0
- aegis_pentest-0.1.0/tests/test_scope.py +75 -0
- aegis_pentest-0.1.0/uv.lock +1950 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# Claude / AI tooling
|
|
13
|
+
.claude/
|
|
14
|
+
AEGIS_MVP_PROMPT.md
|
|
15
|
+
|
|
16
|
+
# Engagement data (client-specific, never commit)
|
|
17
|
+
engagements/*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aegis-pentest
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AEGIS — Adaptive Engagement & Generic Inspection Scanner
|
|
5
|
+
Author-email: Majd Bnat <hey@majdb.com>
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: aiosqlite>=0.20
|
|
8
|
+
Requires-Dist: anthropic>=0.40
|
|
9
|
+
Requires-Dist: anyio>=4.0
|
|
10
|
+
Requires-Dist: dnspython>=2.6
|
|
11
|
+
Requires-Dist: fastmcp>=0.4
|
|
12
|
+
Requires-Dist: httpx>=0.27
|
|
13
|
+
Requires-Dist: jinja2>=3.1
|
|
14
|
+
Requires-Dist: packaging>=24.0
|
|
15
|
+
Requires-Dist: pydantic>=2.0
|
|
16
|
+
Requires-Dist: python-dateutil>=2.9
|
|
17
|
+
Requires-Dist: pyyaml>=6.0
|
|
18
|
+
Requires-Dist: rich>=13.0
|
|
19
|
+
Requires-Dist: sqlmodel>=0.0.21
|
|
20
|
+
Requires-Dist: structlog>=24.0
|
|
21
|
+
Requires-Dist: typer[all]>=0.12
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# aegis
|
|
25
|
+
|
|
26
|
+
**Adaptive Engagement & Generic Inspection Scanner**
|
|
27
|
+
|
|
28
|
+
An autonomous, AI-orchestrated web penetration testing agent. Aegis handles reconnaissance, fingerprinting, vulnerability discovery, and verification so the human pentester focuses on what actually requires human judgment.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## What it is
|
|
33
|
+
|
|
34
|
+
Aegis runs structured, methodology-driven engagements against web targets. It profiles the host environment, fingerprints the target stack, selects relevant tools and tests from the PTES + OWASP WSTG v4.2 playbook, executes them concurrently, and produces a verified findings report with remediation guidance.
|
|
35
|
+
|
|
36
|
+
It is not a Burp Suite replacement. It is the autonomous recon and vuln-discovery layer that feeds the human pentester, eliminating roughly 70% of routine busywork.
|
|
37
|
+
|
|
38
|
+
**Hard constraints built into the runtime:**
|
|
39
|
+
|
|
40
|
+
- Every engagement requires a signed `scope.yaml` before any network egress.
|
|
41
|
+
- Every outbound request is matched against in-scope and out-of-scope rules before the socket opens.
|
|
42
|
+
- Scope violations abort the current task and are written to the audit log.
|
|
43
|
+
- There is no `--force` flag that bypasses scope.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
**Via pipx (recommended):**
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pipx install aegis-pentest
|
|
53
|
+
aegis init
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Via AUR (Arch Linux):**
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
yay -S aegis-pentest
|
|
60
|
+
aegis init
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Requirements:**
|
|
64
|
+
|
|
65
|
+
- Python 3.12+
|
|
66
|
+
- `ANTHROPIC_API_KEY` in environment
|
|
67
|
+
- Pentest toolchain (see `aegis env tools` after init)
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Quickstart
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# First run: profiles host, lists missing tools
|
|
75
|
+
aegis init
|
|
76
|
+
|
|
77
|
+
# Sync the knowledge base (NVD, GHSA, nuclei-templates)
|
|
78
|
+
aegis kb sync
|
|
79
|
+
|
|
80
|
+
# Create a new engagement
|
|
81
|
+
aegis engagement new --client "Acme Corp" --domain "acme.com"
|
|
82
|
+
|
|
83
|
+
# Fill in the authorization details
|
|
84
|
+
vim engagements/2026-05-acme/scope.yaml
|
|
85
|
+
|
|
86
|
+
# Run
|
|
87
|
+
aegis run engagements/2026-05-acme
|
|
88
|
+
|
|
89
|
+
# Generate report
|
|
90
|
+
aegis report engagements/2026-05-acme --format html
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## scope.yaml
|
|
96
|
+
|
|
97
|
+
Aegis refuses to run without this file. No exceptions.
|
|
98
|
+
|
|
99
|
+
```yaml
|
|
100
|
+
engagement_id: "BL-2026-007"
|
|
101
|
+
client: "Acme Corp"
|
|
102
|
+
operator: "Majd Bnat <hey@majdb.com>"
|
|
103
|
+
authorization:
|
|
104
|
+
document_ref: "SOW-2026-007.pdf"
|
|
105
|
+
signed_date: "2026-05-12"
|
|
106
|
+
expiry: "2026-06-12"
|
|
107
|
+
in_scope:
|
|
108
|
+
domains:
|
|
109
|
+
- "*.acme.com"
|
|
110
|
+
- "api-staging.acme.io"
|
|
111
|
+
ips:
|
|
112
|
+
- "203.0.113.0/24"
|
|
113
|
+
out_of_scope:
|
|
114
|
+
- "admin.acme.com"
|
|
115
|
+
- "*.internal.acme.com"
|
|
116
|
+
rules_of_engagement:
|
|
117
|
+
rate_limit_rps: 10
|
|
118
|
+
business_hours_only: false
|
|
119
|
+
destructive_tests: false
|
|
120
|
+
no_credential_stuffing: true
|
|
121
|
+
no_dos_tests: true
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Architecture
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
aegis CLI
|
|
130
|
+
|
|
|
131
|
+
Engagement Manager
|
|
132
|
+
(scope validation, lifecycle, audit log)
|
|
133
|
+
|
|
|
134
|
+
+-----------------+-----------------+
|
|
135
|
+
| | |
|
|
136
|
+
Environment Target Methodology
|
|
137
|
+
Profiler Profiler Engine
|
|
138
|
+
(host info) (fingerprint) (PTES phases)
|
|
139
|
+
| | |
|
|
140
|
+
+--------+--------+--------+--------+
|
|
141
|
+
|
|
|
142
|
+
LLM Orchestrator
|
|
143
|
+
(Haiku / Sonnet / Opus)
|
|
144
|
+
|
|
|
145
|
+
+------------+------------+
|
|
146
|
+
| | |
|
|
147
|
+
Tool Knowledge Findings
|
|
148
|
+
Registry Base DB
|
|
149
|
+
(35+ tools) (NVD/GHSA) (SQLite)
|
|
150
|
+
| |
|
|
151
|
+
Tool Executor Reporter
|
|
152
|
+
(async, sandboxed) (md/html/json)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The orchestrator runs a bounded loop per phase:
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
plan(phase_context) -> execute(action) -> observe(result) -> update(state)
|
|
159
|
+
^ |
|
|
160
|
+
+---------------------------------------------------------------+
|
|
161
|
+
until phase complete OR budget exceeded
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Three independent budgets bound each phase: token budget, wall-clock time, and action count. Whichever trips first ends the phase and triggers finalize mode.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Token model
|
|
169
|
+
|
|
170
|
+
Aegis is designed to complete a full medium-scope engagement for under $2 in LLM tokens. This is achieved through several layered tactics:
|
|
171
|
+
|
|
172
|
+
| Tactic | Impact |
|
|
173
|
+
|---|---|
|
|
174
|
+
| Tiered model routing (Haiku handles ~70% of calls) | -60% cost |
|
|
175
|
+
| Prompt caching on system prompt + engagement context | -40% on input tokens |
|
|
176
|
+
| Parsed tool output, never raw stdout to the LLM | -80% on tool-heavy phases |
|
|
177
|
+
| Structured tool-use schema, no prose planning | -30% output tokens |
|
|
178
|
+
| Methodology-driven action space pruning | -50% wasted calls |
|
|
179
|
+
| SQLite-cached recon reused across phases | variable |
|
|
180
|
+
| Finding deduplication before LLM sees results | -10-30% |
|
|
181
|
+
|
|
182
|
+
Model tiers:
|
|
183
|
+
|
|
184
|
+
| Tier | Model | Used for |
|
|
185
|
+
|---|---|---|
|
|
186
|
+
| NANO | claude-haiku-4-5 | Parsing, classification, summarization |
|
|
187
|
+
| MAIN | claude-sonnet-4-6 | Planning, hypothesis generation, verification probes |
|
|
188
|
+
| DEEP | claude-opus-4-7 | Attack chain analysis, hard reasoning |
|
|
189
|
+
| LOCAL | ollama (optional) | Offline pre-classification |
|
|
190
|
+
|
|
191
|
+
The live cost meter runs in the terminal throughout each phase:
|
|
192
|
+
|
|
193
|
+
```
|
|
194
|
+
Phase: VULN_ANALYSIS [>>>>>>>>--] 80%
|
|
195
|
+
Budget: $0.74 / $5.00 Tokens: 41.2k / 200k Time: 12m / 60m
|
|
196
|
+
Tier breakdown: NANO 24% . MAIN 71% . DEEP 5% Cache hit: 82%
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Tool catalog
|
|
202
|
+
|
|
203
|
+
Aegis wraps 35+ tools. Raw output is never passed to the LLM. Each tool has a typed parser that produces structured `Finding` or `Observation` models. A nmap scan returning 47 open ports becomes 47 `OpenPort` observations of ~80 bytes each, not 200 KB of XML.
|
|
204
|
+
|
|
205
|
+
| Category | Tools |
|
|
206
|
+
|---|---|
|
|
207
|
+
| Subdomain enumeration | subfinder, amass, assetfinder, dnsx |
|
|
208
|
+
| Live host detection | httpx, httprobe |
|
|
209
|
+
| Port scanning | nmap, naabu, rustscan |
|
|
210
|
+
| Web crawling | katana, gospider, hakrawler |
|
|
211
|
+
| Content discovery | ffuf, feroxbuster, gobuster, dirsearch |
|
|
212
|
+
| Tech fingerprinting | whatweb, wappalyzer-cli, httpx -tech-detect |
|
|
213
|
+
| Vulnerability scanning | nuclei, nikto, wpscan, droopescan, joomscan |
|
|
214
|
+
| TLS auditing | testssl.sh, sslscan, sslyze |
|
|
215
|
+
| Parameter discovery | arjun, paramspider, x8 |
|
|
216
|
+
| Secrets | trufflehog, gitleaks |
|
|
217
|
+
| Visual recon | gowitness, aquatone |
|
|
218
|
+
| SQLi verification | sqlmap (safe flags only: --batch --crawl=0 --level=1 --risk=1) |
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Environment profiling
|
|
223
|
+
|
|
224
|
+
On first run, `aegis init` profiles the host and derives auto-tuned concurrency settings:
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
Host: arch-workstation
|
|
228
|
+
OS Arch Linux (rolling, kernel 6.9.3-arch1-1)
|
|
229
|
+
CPU AMD Ryzen 7 5800X . 8 cores / 16 threads . 4.7 GHz
|
|
230
|
+
Memory 32 GB total . 24 GB available
|
|
231
|
+
Repos core, extra, multilib, blackarch
|
|
232
|
+
|
|
233
|
+
Pentest toolchain: 28/35 detected
|
|
234
|
+
nmap 7.95 nuclei 3.2.9 httpx 1.6.6
|
|
235
|
+
ffuf 2.1.0 subfinder 2.6.6 katana 1.1.0
|
|
236
|
+
sqlmap 1.8.5 wpscan 3.8.27 nikto 2.5.0
|
|
237
|
+
gobuster 3.6.0 amass 4.2.0 gowitness 3.0.3
|
|
238
|
+
|
|
239
|
+
Missing: testssl.sh feroxbuster dnsrecon arjun paramspider trufflehog
|
|
240
|
+
-> Run: aegis env install --missing
|
|
241
|
+
|
|
242
|
+
Auto-tuned concurrency:
|
|
243
|
+
nmap_parallelism=16 nuclei_concurrency=32 ffuf_threads=64
|
|
244
|
+
httpx_concurrency=80 max_parallel_tools=4
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## CLI reference
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
aegis init First-run setup and env profile
|
|
253
|
+
aegis env show Display host profile
|
|
254
|
+
aegis env tools Tool inventory
|
|
255
|
+
aegis env install --missing Generate install commands for missing tools
|
|
256
|
+
aegis env refresh Re-detect host profile
|
|
257
|
+
|
|
258
|
+
aegis kb sync [--source nvd|ghsa|nuclei] Sync knowledge base
|
|
259
|
+
aegis kb stats Knowledge base summary
|
|
260
|
+
aegis kb query --product nginx --min-cvss 7 Query CVEs
|
|
261
|
+
|
|
262
|
+
aegis engagement new --client X --domain Y Scaffold engagement dir and scope.yaml
|
|
263
|
+
aegis engagement list List engagements
|
|
264
|
+
|
|
265
|
+
aegis run <dir> [--phase PHASE] Run engagement
|
|
266
|
+
aegis run <dir> --dry-run Preview planned actions
|
|
267
|
+
aegis run <dir> --budget-usd 2.00 Cap spend
|
|
268
|
+
|
|
269
|
+
aegis report <dir> [--format md|html|json] Generate report
|
|
270
|
+
aegis findings list <dir> [--severity high] List findings
|
|
271
|
+
aegis findings verify <finding-id> Re-run verification probe
|
|
272
|
+
aegis findings suppress <finding-id> --reason "..."
|
|
273
|
+
|
|
274
|
+
aegis cost <dir> Detailed cost breakdown
|
|
275
|
+
aegis audit <dir> Full audit log
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
All commands support `--json` for scripting, `-v/-vv/-vvv` for verbosity, `--quiet` for CI.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Configuration
|
|
283
|
+
|
|
284
|
+
Global config lives at `~/.config/aegis/config.toml`. Any key can be overridden per engagement in `engagement_dir/config.toml`.
|
|
285
|
+
|
|
286
|
+
```toml
|
|
287
|
+
[api]
|
|
288
|
+
anthropic_api_key_env = "ANTHROPIC_API_KEY"
|
|
289
|
+
|
|
290
|
+
[models]
|
|
291
|
+
nano = "claude-haiku-4-5-20251001"
|
|
292
|
+
main = "claude-sonnet-4-6"
|
|
293
|
+
deep = "claude-opus-4-7"
|
|
294
|
+
|
|
295
|
+
[models.local]
|
|
296
|
+
enabled = false
|
|
297
|
+
endpoint = "http://localhost:11434"
|
|
298
|
+
model = "qwen2.5:7b"
|
|
299
|
+
|
|
300
|
+
[budgets]
|
|
301
|
+
tokens_per_phase = 30000
|
|
302
|
+
tokens_per_engagement = 200000
|
|
303
|
+
usd_per_engagement = 5.00
|
|
304
|
+
wall_time_per_phase_sec = 1800
|
|
305
|
+
|
|
306
|
+
[caching]
|
|
307
|
+
prompt_cache = true
|
|
308
|
+
kb_cache_dir = "~/.cache/aegis/kb"
|
|
309
|
+
fingerprint_cache_ttl_hours = 168
|
|
310
|
+
|
|
311
|
+
[tooling]
|
|
312
|
+
docker_isolate = false
|
|
313
|
+
default_rate_limit_rps = 10
|
|
314
|
+
respect_robots_txt = false
|
|
315
|
+
|
|
316
|
+
[reporting]
|
|
317
|
+
default_format = "html"
|
|
318
|
+
include_audit_log = true
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Tech stack
|
|
324
|
+
|
|
325
|
+
| Layer | Choice |
|
|
326
|
+
|---|---|
|
|
327
|
+
| Language | Python 3.12+ |
|
|
328
|
+
| CLI | Typer + Rich |
|
|
329
|
+
| Async | asyncio + anyio |
|
|
330
|
+
| HTTP | httpx (async, HTTP/2) |
|
|
331
|
+
| Models | Pydantic v2 |
|
|
332
|
+
| Storage | SQLite + SQLModel |
|
|
333
|
+
| LLM | Anthropic SDK (Claude) |
|
|
334
|
+
| Templating | Jinja2 |
|
|
335
|
+
| Logging | structlog + rich |
|
|
336
|
+
| Packaging | uv (dev), hatch (build) |
|
|
337
|
+
| Testing | pytest + pytest-asyncio + respx |
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## License
|
|
342
|
+
|
|
343
|
+
MIT. Use responsibly and only against systems you are authorized to test.
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
Built by [Majd Bnat](mailto:hey@majdb.com)
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# aegis
|
|
2
|
+
|
|
3
|
+
**Adaptive Engagement & Generic Inspection Scanner**
|
|
4
|
+
|
|
5
|
+
An autonomous, AI-orchestrated web penetration testing agent. Aegis handles reconnaissance, fingerprinting, vulnerability discovery, and verification so the human pentester focuses on what actually requires human judgment.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What it is
|
|
10
|
+
|
|
11
|
+
Aegis runs structured, methodology-driven engagements against web targets. It profiles the host environment, fingerprints the target stack, selects relevant tools and tests from the PTES + OWASP WSTG v4.2 playbook, executes them concurrently, and produces a verified findings report with remediation guidance.
|
|
12
|
+
|
|
13
|
+
It is not a Burp Suite replacement. It is the autonomous recon and vuln-discovery layer that feeds the human pentester, eliminating roughly 70% of routine busywork.
|
|
14
|
+
|
|
15
|
+
**Hard constraints built into the runtime:**
|
|
16
|
+
|
|
17
|
+
- Every engagement requires a signed `scope.yaml` before any network egress.
|
|
18
|
+
- Every outbound request is matched against in-scope and out-of-scope rules before the socket opens.
|
|
19
|
+
- Scope violations abort the current task and are written to the audit log.
|
|
20
|
+
- There is no `--force` flag that bypasses scope.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
**Via pipx (recommended):**
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pipx install aegis-pentest
|
|
30
|
+
aegis init
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Via AUR (Arch Linux):**
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
yay -S aegis-pentest
|
|
37
|
+
aegis init
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Requirements:**
|
|
41
|
+
|
|
42
|
+
- Python 3.12+
|
|
43
|
+
- `ANTHROPIC_API_KEY` in environment
|
|
44
|
+
- Pentest toolchain (see `aegis env tools` after init)
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Quickstart
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# First run: profiles host, lists missing tools
|
|
52
|
+
aegis init
|
|
53
|
+
|
|
54
|
+
# Sync the knowledge base (NVD, GHSA, nuclei-templates)
|
|
55
|
+
aegis kb sync
|
|
56
|
+
|
|
57
|
+
# Create a new engagement
|
|
58
|
+
aegis engagement new --client "Acme Corp" --domain "acme.com"
|
|
59
|
+
|
|
60
|
+
# Fill in the authorization details
|
|
61
|
+
vim engagements/2026-05-acme/scope.yaml
|
|
62
|
+
|
|
63
|
+
# Run
|
|
64
|
+
aegis run engagements/2026-05-acme
|
|
65
|
+
|
|
66
|
+
# Generate report
|
|
67
|
+
aegis report engagements/2026-05-acme --format html
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## scope.yaml
|
|
73
|
+
|
|
74
|
+
Aegis refuses to run without this file. No exceptions.
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
engagement_id: "BL-2026-007"
|
|
78
|
+
client: "Acme Corp"
|
|
79
|
+
operator: "Majd Bnat <hey@majdb.com>"
|
|
80
|
+
authorization:
|
|
81
|
+
document_ref: "SOW-2026-007.pdf"
|
|
82
|
+
signed_date: "2026-05-12"
|
|
83
|
+
expiry: "2026-06-12"
|
|
84
|
+
in_scope:
|
|
85
|
+
domains:
|
|
86
|
+
- "*.acme.com"
|
|
87
|
+
- "api-staging.acme.io"
|
|
88
|
+
ips:
|
|
89
|
+
- "203.0.113.0/24"
|
|
90
|
+
out_of_scope:
|
|
91
|
+
- "admin.acme.com"
|
|
92
|
+
- "*.internal.acme.com"
|
|
93
|
+
rules_of_engagement:
|
|
94
|
+
rate_limit_rps: 10
|
|
95
|
+
business_hours_only: false
|
|
96
|
+
destructive_tests: false
|
|
97
|
+
no_credential_stuffing: true
|
|
98
|
+
no_dos_tests: true
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Architecture
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
aegis CLI
|
|
107
|
+
|
|
|
108
|
+
Engagement Manager
|
|
109
|
+
(scope validation, lifecycle, audit log)
|
|
110
|
+
|
|
|
111
|
+
+-----------------+-----------------+
|
|
112
|
+
| | |
|
|
113
|
+
Environment Target Methodology
|
|
114
|
+
Profiler Profiler Engine
|
|
115
|
+
(host info) (fingerprint) (PTES phases)
|
|
116
|
+
| | |
|
|
117
|
+
+--------+--------+--------+--------+
|
|
118
|
+
|
|
|
119
|
+
LLM Orchestrator
|
|
120
|
+
(Haiku / Sonnet / Opus)
|
|
121
|
+
|
|
|
122
|
+
+------------+------------+
|
|
123
|
+
| | |
|
|
124
|
+
Tool Knowledge Findings
|
|
125
|
+
Registry Base DB
|
|
126
|
+
(35+ tools) (NVD/GHSA) (SQLite)
|
|
127
|
+
| |
|
|
128
|
+
Tool Executor Reporter
|
|
129
|
+
(async, sandboxed) (md/html/json)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The orchestrator runs a bounded loop per phase:
|
|
133
|
+
|
|
134
|
+
```
|
|
135
|
+
plan(phase_context) -> execute(action) -> observe(result) -> update(state)
|
|
136
|
+
^ |
|
|
137
|
+
+---------------------------------------------------------------+
|
|
138
|
+
until phase complete OR budget exceeded
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Three independent budgets bound each phase: token budget, wall-clock time, and action count. Whichever trips first ends the phase and triggers finalize mode.
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Token model
|
|
146
|
+
|
|
147
|
+
Aegis is designed to complete a full medium-scope engagement for under $2 in LLM tokens. This is achieved through several layered tactics:
|
|
148
|
+
|
|
149
|
+
| Tactic | Impact |
|
|
150
|
+
|---|---|
|
|
151
|
+
| Tiered model routing (Haiku handles ~70% of calls) | -60% cost |
|
|
152
|
+
| Prompt caching on system prompt + engagement context | -40% on input tokens |
|
|
153
|
+
| Parsed tool output, never raw stdout to the LLM | -80% on tool-heavy phases |
|
|
154
|
+
| Structured tool-use schema, no prose planning | -30% output tokens |
|
|
155
|
+
| Methodology-driven action space pruning | -50% wasted calls |
|
|
156
|
+
| SQLite-cached recon reused across phases | variable |
|
|
157
|
+
| Finding deduplication before LLM sees results | -10-30% |
|
|
158
|
+
|
|
159
|
+
Model tiers:
|
|
160
|
+
|
|
161
|
+
| Tier | Model | Used for |
|
|
162
|
+
|---|---|---|
|
|
163
|
+
| NANO | claude-haiku-4-5 | Parsing, classification, summarization |
|
|
164
|
+
| MAIN | claude-sonnet-4-6 | Planning, hypothesis generation, verification probes |
|
|
165
|
+
| DEEP | claude-opus-4-7 | Attack chain analysis, hard reasoning |
|
|
166
|
+
| LOCAL | ollama (optional) | Offline pre-classification |
|
|
167
|
+
|
|
168
|
+
The live cost meter runs in the terminal throughout each phase:
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
Phase: VULN_ANALYSIS [>>>>>>>>--] 80%
|
|
172
|
+
Budget: $0.74 / $5.00 Tokens: 41.2k / 200k Time: 12m / 60m
|
|
173
|
+
Tier breakdown: NANO 24% . MAIN 71% . DEEP 5% Cache hit: 82%
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Tool catalog
|
|
179
|
+
|
|
180
|
+
Aegis wraps 35+ tools. Raw output is never passed to the LLM. Each tool has a typed parser that produces structured `Finding` or `Observation` models. A nmap scan returning 47 open ports becomes 47 `OpenPort` observations of ~80 bytes each, not 200 KB of XML.
|
|
181
|
+
|
|
182
|
+
| Category | Tools |
|
|
183
|
+
|---|---|
|
|
184
|
+
| Subdomain enumeration | subfinder, amass, assetfinder, dnsx |
|
|
185
|
+
| Live host detection | httpx, httprobe |
|
|
186
|
+
| Port scanning | nmap, naabu, rustscan |
|
|
187
|
+
| Web crawling | katana, gospider, hakrawler |
|
|
188
|
+
| Content discovery | ffuf, feroxbuster, gobuster, dirsearch |
|
|
189
|
+
| Tech fingerprinting | whatweb, wappalyzer-cli, httpx -tech-detect |
|
|
190
|
+
| Vulnerability scanning | nuclei, nikto, wpscan, droopescan, joomscan |
|
|
191
|
+
| TLS auditing | testssl.sh, sslscan, sslyze |
|
|
192
|
+
| Parameter discovery | arjun, paramspider, x8 |
|
|
193
|
+
| Secrets | trufflehog, gitleaks |
|
|
194
|
+
| Visual recon | gowitness, aquatone |
|
|
195
|
+
| SQLi verification | sqlmap (safe flags only: --batch --crawl=0 --level=1 --risk=1) |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Environment profiling
|
|
200
|
+
|
|
201
|
+
On first run, `aegis init` profiles the host and derives auto-tuned concurrency settings:
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
Host: arch-workstation
|
|
205
|
+
OS Arch Linux (rolling, kernel 6.9.3-arch1-1)
|
|
206
|
+
CPU AMD Ryzen 7 5800X . 8 cores / 16 threads . 4.7 GHz
|
|
207
|
+
Memory 32 GB total . 24 GB available
|
|
208
|
+
Repos core, extra, multilib, blackarch
|
|
209
|
+
|
|
210
|
+
Pentest toolchain: 28/35 detected
|
|
211
|
+
nmap 7.95 nuclei 3.2.9 httpx 1.6.6
|
|
212
|
+
ffuf 2.1.0 subfinder 2.6.6 katana 1.1.0
|
|
213
|
+
sqlmap 1.8.5 wpscan 3.8.27 nikto 2.5.0
|
|
214
|
+
gobuster 3.6.0 amass 4.2.0 gowitness 3.0.3
|
|
215
|
+
|
|
216
|
+
Missing: testssl.sh feroxbuster dnsrecon arjun paramspider trufflehog
|
|
217
|
+
-> Run: aegis env install --missing
|
|
218
|
+
|
|
219
|
+
Auto-tuned concurrency:
|
|
220
|
+
nmap_parallelism=16 nuclei_concurrency=32 ffuf_threads=64
|
|
221
|
+
httpx_concurrency=80 max_parallel_tools=4
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## CLI reference
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
aegis init First-run setup and env profile
|
|
230
|
+
aegis env show Display host profile
|
|
231
|
+
aegis env tools Tool inventory
|
|
232
|
+
aegis env install --missing Generate install commands for missing tools
|
|
233
|
+
aegis env refresh Re-detect host profile
|
|
234
|
+
|
|
235
|
+
aegis kb sync [--source nvd|ghsa|nuclei] Sync knowledge base
|
|
236
|
+
aegis kb stats Knowledge base summary
|
|
237
|
+
aegis kb query --product nginx --min-cvss 7 Query CVEs
|
|
238
|
+
|
|
239
|
+
aegis engagement new --client X --domain Y Scaffold engagement dir and scope.yaml
|
|
240
|
+
aegis engagement list List engagements
|
|
241
|
+
|
|
242
|
+
aegis run <dir> [--phase PHASE] Run engagement
|
|
243
|
+
aegis run <dir> --dry-run Preview planned actions
|
|
244
|
+
aegis run <dir> --budget-usd 2.00 Cap spend
|
|
245
|
+
|
|
246
|
+
aegis report <dir> [--format md|html|json] Generate report
|
|
247
|
+
aegis findings list <dir> [--severity high] List findings
|
|
248
|
+
aegis findings verify <finding-id> Re-run verification probe
|
|
249
|
+
aegis findings suppress <finding-id> --reason "..."
|
|
250
|
+
|
|
251
|
+
aegis cost <dir> Detailed cost breakdown
|
|
252
|
+
aegis audit <dir> Full audit log
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
All commands support `--json` for scripting, `-v/-vv/-vvv` for verbosity, `--quiet` for CI.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Configuration
|
|
260
|
+
|
|
261
|
+
Global config lives at `~/.config/aegis/config.toml`. Any key can be overridden per engagement in `engagement_dir/config.toml`.
|
|
262
|
+
|
|
263
|
+
```toml
|
|
264
|
+
[api]
|
|
265
|
+
anthropic_api_key_env = "ANTHROPIC_API_KEY"
|
|
266
|
+
|
|
267
|
+
[models]
|
|
268
|
+
nano = "claude-haiku-4-5-20251001"
|
|
269
|
+
main = "claude-sonnet-4-6"
|
|
270
|
+
deep = "claude-opus-4-7"
|
|
271
|
+
|
|
272
|
+
[models.local]
|
|
273
|
+
enabled = false
|
|
274
|
+
endpoint = "http://localhost:11434"
|
|
275
|
+
model = "qwen2.5:7b"
|
|
276
|
+
|
|
277
|
+
[budgets]
|
|
278
|
+
tokens_per_phase = 30000
|
|
279
|
+
tokens_per_engagement = 200000
|
|
280
|
+
usd_per_engagement = 5.00
|
|
281
|
+
wall_time_per_phase_sec = 1800
|
|
282
|
+
|
|
283
|
+
[caching]
|
|
284
|
+
prompt_cache = true
|
|
285
|
+
kb_cache_dir = "~/.cache/aegis/kb"
|
|
286
|
+
fingerprint_cache_ttl_hours = 168
|
|
287
|
+
|
|
288
|
+
[tooling]
|
|
289
|
+
docker_isolate = false
|
|
290
|
+
default_rate_limit_rps = 10
|
|
291
|
+
respect_robots_txt = false
|
|
292
|
+
|
|
293
|
+
[reporting]
|
|
294
|
+
default_format = "html"
|
|
295
|
+
include_audit_log = true
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Tech stack
|
|
301
|
+
|
|
302
|
+
| Layer | Choice |
|
|
303
|
+
|---|---|
|
|
304
|
+
| Language | Python 3.12+ |
|
|
305
|
+
| CLI | Typer + Rich |
|
|
306
|
+
| Async | asyncio + anyio |
|
|
307
|
+
| HTTP | httpx (async, HTTP/2) |
|
|
308
|
+
| Models | Pydantic v2 |
|
|
309
|
+
| Storage | SQLite + SQLModel |
|
|
310
|
+
| LLM | Anthropic SDK (Claude) |
|
|
311
|
+
| Templating | Jinja2 |
|
|
312
|
+
| Logging | structlog + rich |
|
|
313
|
+
| Packaging | uv (dev), hatch (build) |
|
|
314
|
+
| Testing | pytest + pytest-asyncio + respx |
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## License
|
|
319
|
+
|
|
320
|
+
MIT. Use responsibly and only against systems you are authorized to test.
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
Built by [Majd Bnat](mailto:hey@majdb.com)
|