mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-06-30 07:15:30 +02:00
v3.5.1: attack-chain agents (12) + per-project .neurosploit/ persistence & resume
Chaining: - agents_md/chains/ (12 multi-stage exploitation playbooks): SQLi→RCE→LPE, SSRF→AWS-creds, SSRF→RCE, upload→RCE, upload→LFI→RCE→LPE, XSS→ATO, IDOR→ATO, SSTI→RCE→cloud, default-creds→domain, deserialization→RCE, exposed-git→RCE, subdomain-takeover→trusted-abuse. Each stage proven by a tool receipt before advancing; reports chains_from edges. - Loaded as a `chains` category (→ 329 agents). chain_round now injects the chain recipes as a menu so the LLM applies proven multi-stage paths. Persistence (no DB — structured state): - Per-project `<cwd>/.neurosploit/` holding session.json (config), runs.json (history), history.txt (readline). REPL resumes target/repo/auth/focus/models on reopen; saves on /run and /quit. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
# Default Creds → Foothold → Domain Compromise Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: default/weak creds → host foothold → AD escalation → domain dominance.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Chain an exposed credential into Active Directory domain compromise.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Get the foothold
|
||||
- Authenticate with the default/weak/reused credential (SSH/WinRM/SMB/web)
|
||||
|
||||
### Stage 2. Enumerate AD
|
||||
- From the foothold, run BloodHound/netexec; map attack paths, roastable accounts, ACLs
|
||||
|
||||
### Stage 3. Escalate in AD
|
||||
- Kerberoast/AS-REP-roast, abuse an ACL edge, or relay — recover higher-priv creds
|
||||
|
||||
### Stage 4. Reach domain dominance
|
||||
- Demonstrate DCSync or DA-equivalent access (single test account) proving the path
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: Default Creds → Foothold → Domain Compromise Chain
|
||||
- Severity: Critical
|
||||
- CWE: CWE-798
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Domain compromise from a single weak/default credential
|
||||
- Remediation: Rotate defaults; unique strong passwords; tiered admin; monitor
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Insecure Deserialization → RCE Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: untrusted deserialization → gadget chain → remote code execution.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Turn a deserialization sink into reliable code execution.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Locate the sink
|
||||
- Identify where attacker data is deserialized (cookie/param/file/RPC); fingerprint the format/library
|
||||
|
||||
### Stage 2. Build the gadget
|
||||
- Select a working gadget chain (ysoserial/ysoserial.net/PyYAML/pickle) for the target stack
|
||||
|
||||
### Stage 3. Execute
|
||||
- Deliver the payload to the sink
|
||||
|
||||
### Stage 4. Confirm
|
||||
- Prove execution via OOB callback or command output with a unique marker
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: Insecure Deserialization → RCE Chain
|
||||
- Severity: Critical
|
||||
- CWE: CWE-502
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Remote code execution via unsafe object deserialization
|
||||
- Remediation: Never deserialize untrusted data; allowlist types; safe formats
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Exposed .git/.env → Secret → RCE Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: exposed source/secrets → recovered credentials → authenticated RCE.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Chain leaked source/secrets into authenticated code execution.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Recover the source/secrets
|
||||
- Dump exposed `.git` (git-dumper) or read `.env`/config; extract keys/creds/tokens
|
||||
|
||||
### Stage 2. Validate the secrets
|
||||
- Confirm a recovered credential/key is live (admin panel, cloud, DB, CI)
|
||||
|
||||
### Stage 3. Gain execution
|
||||
- Use the access to deploy code / run a CI job / write a webshell / exec via admin feature
|
||||
|
||||
### Stage 4. Confirm RCE
|
||||
- Prove command execution with output
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: Exposed .git/.env → Secret → RCE Chain
|
||||
- Severity: High
|
||||
- CWE: CWE-527
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Code execution using credentials recovered from exposed source/secrets
|
||||
- Remediation: Block dotfiles from web; rotate leaked secrets; vault storage
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,42 @@
|
||||
# IDOR → Mass Account Takeover Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: IDOR → cross-account data → credential/role manipulation → takeover.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Chain object-level authz failure into taking over arbitrary accounts.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Confirm the IDOR
|
||||
- Access another user's object with your session, proven by their data
|
||||
|
||||
### Stage 2. Find a state-changing IDOR
|
||||
- Locate IDOR on email/password/role/API-key endpoints
|
||||
|
||||
### Stage 3. Manipulate the victim account
|
||||
- Change a victim's email or reset token / elevate role via the IDOR
|
||||
|
||||
### Stage 4. Confirm takeover
|
||||
- Log in as / act as the victim; demonstrate control
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: IDOR → Mass Account Takeover Chain
|
||||
- Severity: High
|
||||
- CWE: CWE-639
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Mass account takeover via broken object-level authorization
|
||||
- Remediation: Enforce per-object ownership on every endpoint; indirect references
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,45 @@
|
||||
# SQLi → RCE → Local PrivEsc Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: SQL injection → command execution → local privilege escalation.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Turn a database-layer injection into root/SYSTEM on the host.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Exploit the SQL injection
|
||||
- Confirm injection (error/boolean/time); identify DBMS and privileges
|
||||
- Enumerate whether stacked queries / FILE / xp_cmdshell / INTO OUTFILE are available
|
||||
|
||||
### Stage 2. Pivot SQLi → RCE
|
||||
- MSSQL: enable & use `xp_cmdshell`; MySQL: `INTO OUTFILE` a webshell to a known web path; PostgreSQL: `COPY ... PROGRAM`
|
||||
- Confirm OS command execution with `id`/`whoami` output
|
||||
|
||||
### Stage 3. Establish a foothold
|
||||
- Drop/upgrade to a stable shell as the web/db service user
|
||||
|
||||
### Stage 4. Local privilege escalation
|
||||
- Enumerate SUID/sudo/cron/kernel (Linux) or token/service/unquoted-path (Windows)
|
||||
- Escalate to root/SYSTEM and prove with a privileged command output
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: SQLi → RCE → Local PrivEsc Chain
|
||||
- Severity: Critical
|
||||
- CWE: CWE-89
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Full host compromise originating from a web injection
|
||||
- Remediation: Parameterize queries; least-privilege DB account; harden host; patch local vectors
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,45 @@
|
||||
# SSRF → AWS Credential Compromise Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: SSRF → cloud metadata → IAM credentials → cloud account access.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Convert a server-side request forgery into valid AWS credentials and account access.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Confirm the SSRF primitive
|
||||
- Find a server-side fetch you control (url/webhook/import/pdf/image param)
|
||||
- Prove it reaches an attacker-controlled / internal host
|
||||
|
||||
### Stage 2. Reach the metadata service
|
||||
- IMDSv2: PUT `/latest/api/token` then GET with the token header; else IMDSv1 GET
|
||||
- Retrieve `/latest/meta-data/iam/security-credentials/<role>`
|
||||
|
||||
### Stage 3. Harvest IAM credentials
|
||||
- Capture AccessKeyId/SecretAccessKey/Token from the metadata response
|
||||
|
||||
### Stage 4. Use the credentials (in scope)
|
||||
- `aws sts get-caller-identity` to confirm; enumerate permitted actions read-only
|
||||
- Prove access to at least one resource the role can reach
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: SSRF → AWS Credential Compromise Chain
|
||||
- Severity: Critical
|
||||
- CWE: CWE-918
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Cloud account compromise via stolen IAM role credentials
|
||||
- Remediation: Enforce IMDSv2 hop-limit=1; egress allowlists; SSRF input validation; scoped IAM roles
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,43 @@
|
||||
# SSRF → RCE Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: SSRF → internal service abuse → remote code execution.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Escalate an SSRF into code execution via a reachable internal service.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Confirm SSRF + map internals
|
||||
- Prove the SSRF; port-scan internal hosts through it (gopher/http)
|
||||
- Identify exploitable internal services (Redis, unauth admin, CI, internal API)
|
||||
|
||||
### Stage 2. Weaponize the internal service
|
||||
- e.g. Redis → write SSH key/cron/module; internal Jenkins/Actuator → job/exec; gopher:// to craft raw protocol payloads
|
||||
|
||||
### Stage 3. Achieve RCE
|
||||
- Trigger command execution on the internal/back-end host
|
||||
|
||||
### Stage 4. Confirm
|
||||
- Prove execution with an OOB callback or command output tied to a unique marker
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: SSRF → RCE Chain
|
||||
- Severity: Critical
|
||||
- CWE: CWE-918
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Remote code execution pivoted through an internal service
|
||||
- Remediation: Egress controls; authenticate internal services; SSRF allowlists
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,42 @@
|
||||
# SSTI → RCE → Cloud Pivot Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: template injection → RCE → host creds → cloud/lateral movement.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Go from template injection to code execution to cloud or lateral access.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Confirm SSTI → RCE
|
||||
- Fingerprint the engine (`{{7*7}}` etc.); use the gadget to execute a command; prove with output
|
||||
|
||||
### Stage 2. Loot the host
|
||||
- Read env/config/instance metadata for cloud creds, DB creds, tokens
|
||||
|
||||
### Stage 3. Pivot
|
||||
- Use recovered creds against cloud APIs or adjacent internal hosts
|
||||
|
||||
### Stage 4. Confirm impact
|
||||
- Prove access to a cloud resource or a second host with evidence
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: SSTI → RCE → Cloud Pivot Chain
|
||||
- Severity: Critical
|
||||
- CWE: CWE-1336
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Cloud/lateral compromise originating from template injection
|
||||
- Remediation: Never render user input as templates; sandbox; scope host IAM/creds
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Subdomain Takeover → Trusted Phishing/Cookie Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: dangling DNS → subdomain takeover → trusted-origin abuse.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Chain a dangling record into hosting attacker content on a trusted subdomain.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Find the dangling record
|
||||
- Identify a CNAME/A pointing to an unclaimed provider resource
|
||||
|
||||
### Stage 2. Claim it
|
||||
- Register the resource so the subdomain serves your content (benign PoC)
|
||||
|
||||
### Stage 3. Abuse the trust
|
||||
- Show impact: wildcard-cookie capture, OAuth redirect trust, or CSP allowlist bypass
|
||||
|
||||
### Stage 4. Confirm
|
||||
- Demonstrate the concrete trusted-origin abuse with evidence
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: Subdomain Takeover → Trusted Phishing/Cookie Chain
|
||||
- Severity: High
|
||||
- CWE: CWE-350
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Trusted-origin abuse (cookie theft / phishing / OAuth) via a taken-over subdomain
|
||||
- Remediation: Remove dangling DNS; monitor; scope cookies/CSP per-host
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,42 @@
|
||||
# Upload → LFI → RCE → LPE Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: file upload + local file inclusion → log/session poisoning → RCE → privilege escalation.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Chain a benign upload and an LFI into code execution and then root.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Confirm the LFI
|
||||
- Prove local file inclusion (read /etc/passwd or app config); identify wrappers (php://, data://, zip://)
|
||||
|
||||
### Stage 2. Plant controllable content via upload
|
||||
- Upload a file whose path/content you can later include (image with PHP, zip for zip:// , or use the LFI to read your uploaded file)
|
||||
|
||||
### Stage 3. LFI → RCE
|
||||
- Include the planted file, or poison logs/session/`/proc/self/environ` then include it to execute code
|
||||
|
||||
### Stage 4. Confirm RCE then escalate
|
||||
- Prove command execution; then enumerate and perform local privilege escalation to root/SYSTEM
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: Upload → LFI → RCE → LPE Chain
|
||||
- Severity: Critical
|
||||
- CWE: CWE-98
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Host compromise from a non-executable upload chained through LFI
|
||||
- Remediation: Fix LFI (allowlist includes); validate uploads; harden host
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,43 @@
|
||||
# File Upload → RCE Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: insecure file upload → webshell → remote code execution.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Turn an unrestricted/insecure upload into code execution.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Probe the upload
|
||||
- Map accepted types/extensions, storage path, and how files are served
|
||||
- Test bypasses: double extension, content-type spoof, magic-byte prefix, null byte, .htaccess/.phar
|
||||
|
||||
### Stage 2. Upload a payload
|
||||
- Place a minimal webshell/handler in a web-served, executable location
|
||||
|
||||
### Stage 3. Locate & trigger
|
||||
- Find the served URL of the upload; request it to execute
|
||||
|
||||
### Stage 4. Confirm RCE
|
||||
- Run `id`/`whoami`; capture output proving execution
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: File Upload → RCE Chain
|
||||
- Severity: Critical
|
||||
- CWE: CWE-434
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Remote code execution via uploaded executable content
|
||||
- Remediation: Validate type by content; randomize names; store outside webroot; non-exec storage
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -0,0 +1,42 @@
|
||||
# XSS → Session/Account Takeover Chain Agent
|
||||
|
||||
## User Prompt
|
||||
You are executing a multi-stage ATTACK CHAIN against **{target}**: stored/reflected XSS → session or token theft → account takeover.
|
||||
|
||||
**Recon Context / prior findings:**
|
||||
{recon_json}
|
||||
|
||||
**GOAL:** Escalate XSS into full takeover of a victim (incl. admin) account.
|
||||
|
||||
**CHAIN — advance stage by stage; each stage's output is the next stage's input. Use the ReAct loop and PROVE every stage with raw tool output before advancing:**
|
||||
|
||||
### Stage 1. Prove execution
|
||||
- Confirm the payload executes in the victim's browser context (Playwright: alert/DOM), not just reflects
|
||||
|
||||
### Stage 2. Steal the session
|
||||
- Exfiltrate the session cookie/JWT/CSRF token to a collaborator, or perform actions in-context if HttpOnly
|
||||
|
||||
### Stage 3. Take over the account
|
||||
- Replay the stolen session, or change email/password/MFA via in-context requests
|
||||
|
||||
### Stage 4. Confirm + escalate
|
||||
- Prove control of the victim account; target an admin for privilege escalation
|
||||
|
||||
### 5. Report Format
|
||||
Report the chain as ONE finding (plus per-stage evidence):
|
||||
```
|
||||
FINDING:
|
||||
- Title: XSS → Session/Account Takeover Chain
|
||||
- Severity: High
|
||||
- CWE: CWE-79
|
||||
- Endpoint: [entry point]
|
||||
- Vector: [the full chain, stage by stage]
|
||||
- Payload: [the key payloads/commands per stage]
|
||||
- Evidence: [raw output proving EACH stage actually executed]
|
||||
- Impact: Account takeover (incl. privileged) via client-side execution
|
||||
- Remediation: Output encoding + CSP; HttpOnly/SameSite cookies; rotate tokens
|
||||
- chains_from: [ids of the prerequisite findings this builds on]
|
||||
```
|
||||
|
||||
## System Prompt
|
||||
You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is proven with a real tool receipt (raw output) — never assume a stage worked. If a stage can't be proven, stop and report the chain up to the last proven stage; do not claim the full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must carry its own evidence. Credits: Joas A Santos & Red Team Leaders.
|
||||
@@ -201,8 +201,8 @@ async fn main() -> anyhow::Result<()> {
|
||||
Cmd::Agents => {
|
||||
let lib = agents::load(&base);
|
||||
println!(
|
||||
"{{\"vulns\":{},\"recon\":{},\"code\":{},\"infra\":{},\"meta\":{},\"total\":{}}}",
|
||||
lib.vulns.len(), lib.recon.len(), lib.code.len(), lib.infra.len(), lib.meta.len(), lib.total()
|
||||
"{{\"vulns\":{},\"recon\":{},\"code\":{},\"infra\":{},\"chains\":{},\"meta\":{},\"total\":{}}}",
|
||||
lib.vulns.len(), lib.recon.len(), lib.code.len(), lib.infra.len(), lib.chains.len(), lib.meta.len(), lib.total()
|
||||
);
|
||||
}
|
||||
Cmd::Models => {
|
||||
|
||||
@@ -139,13 +139,12 @@ enum Reader {
|
||||
}
|
||||
|
||||
impl Reader {
|
||||
fn new(base: &Path) -> Reader {
|
||||
fn new(_base: &Path) -> Reader {
|
||||
if std::io::stdin().is_terminal() {
|
||||
let cfg = Config::builder().auto_add_history(false).build();
|
||||
if let Ok(mut ed) = Editor::<NsHelper, FileHistory>::with_config(cfg) {
|
||||
ed.set_helper(Some(NsHelper));
|
||||
let hist = base.join("data").join("repl_history.txt");
|
||||
std::fs::create_dir_all(hist.parent().unwrap()).ok();
|
||||
let hist = proj_dir().join("history.txt");
|
||||
let _ = ed.load_history(&hist);
|
||||
return Reader::Rl(Box::new(ed), hist);
|
||||
}
|
||||
@@ -200,9 +199,11 @@ pub async fn repl(base: &Path) -> anyhow::Result<()> {
|
||||
println!(" Type \x1b[36m/help\x1b[0m to start, \x1b[36m/run\x1b[0m to launch, \x1b[36m/quit\x1b[0m to exit. (↑/↓ recalls commands)\n");
|
||||
|
||||
let mut s = Session::default();
|
||||
let resumed = load_session(&mut s);
|
||||
let mut history: Vec<RunRecord> = load_runs(base);
|
||||
if !history.is_empty() {
|
||||
println!(" loaded {} past run(s) — /runs to list\n", history.len());
|
||||
if resumed || !history.is_empty() {
|
||||
println!(" ↻ resumed project session from {} — {} past run(s)\n",
|
||||
proj_dir().display(), history.len());
|
||||
}
|
||||
let mut reader = Reader::new(base);
|
||||
show(&s);
|
||||
@@ -281,12 +282,12 @@ pub async fn repl(base: &Path) -> anyhow::Result<()> {
|
||||
"/votes" => { s.vote_n = arg.parse().unwrap_or(s.vote_n); println!(" votes: {}", s.vote_n); }
|
||||
"/agents" => { s.max_agents = arg.parse().unwrap_or(s.max_agents); println!(" max agents: {}", s.max_agents); }
|
||||
"/clear" => { print!("\x1b[2J\x1b[H"); }
|
||||
"/run" | "/go" => { run(base, &s, &mut history).await; save_runs(base, &history); }
|
||||
"/run" | "/go" => { save_session(&s); run(base, &s, &mut history).await; save_runs(base, &history); }
|
||||
"/runs" | "/history" => list_runs(&history),
|
||||
"/results" => results(&history, arg),
|
||||
"/report" => open_report(&history, arg),
|
||||
"/status" => run_status(&history, arg),
|
||||
"/quit" | "/exit" | "/q" => { println!(" bye."); break; }
|
||||
"/quit" | "/exit" | "/q" => { save_session(&s); println!(" session saved → {} · bye.", proj_dir().display()); break; }
|
||||
other => println!(" unknown command '{other}' — try /help"),
|
||||
}
|
||||
}
|
||||
@@ -423,20 +424,61 @@ async fn run(base: &Path, s: &Session, history: &mut Vec<RunRecord>) {
|
||||
}
|
||||
}
|
||||
|
||||
fn runs_path(base: &Path) -> std::path::PathBuf {
|
||||
base.join("data").join("repl_runs.json")
|
||||
/// Project-local store: `<cwd>/.neurosploit/` so each project keeps its own
|
||||
/// session, run history and command history (resume on reopen). No DB needed —
|
||||
/// it's structured state, not semantic search.
|
||||
pub(crate) fn proj_dir() -> std::path::PathBuf {
|
||||
let d = std::env::current_dir().unwrap_or_else(|_| std::path::PathBuf::from(".")).join(".neurosploit");
|
||||
std::fs::create_dir_all(&d).ok();
|
||||
d
|
||||
}
|
||||
fn load_runs(base: &Path) -> Vec<RunRecord> {
|
||||
std::fs::read_to_string(runs_path(base)).ok()
|
||||
fn runs_path(_base: &Path) -> std::path::PathBuf { proj_dir().join("runs.json") }
|
||||
fn load_runs(_base: &Path) -> Vec<RunRecord> {
|
||||
std::fs::read_to_string(runs_path(_base)).ok()
|
||||
.and_then(|t| serde_json::from_str(&t).ok())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
fn save_runs(base: &Path, history: &[RunRecord]) {
|
||||
let p = runs_path(base);
|
||||
if let Some(dir) = p.parent() { std::fs::create_dir_all(dir).ok(); }
|
||||
fn save_runs(_base: &Path, history: &[RunRecord]) {
|
||||
let p = runs_path(_base);
|
||||
if let Ok(j) = serde_json::to_string_pretty(history) { std::fs::write(p, j).ok(); }
|
||||
}
|
||||
|
||||
/// Persistable snapshot of the session config (resume across restarts).
|
||||
#[derive(Serialize, Deserialize, Default)]
|
||||
struct Snapshot {
|
||||
models: Vec<String>,
|
||||
subscription: bool,
|
||||
mcp: bool,
|
||||
vote_n: usize,
|
||||
max_agents: usize,
|
||||
target: Option<String>,
|
||||
repo: Option<String>,
|
||||
auth: Option<String>,
|
||||
creds: Option<String>,
|
||||
instructions: Option<String>,
|
||||
}
|
||||
fn session_path() -> std::path::PathBuf { proj_dir().join("session.json") }
|
||||
fn save_session(s: &Session) {
|
||||
let snap = Snapshot {
|
||||
models: s.models.clone(), subscription: s.subscription, mcp: s.mcp,
|
||||
vote_n: s.vote_n, max_agents: s.max_agents, target: s.target.clone(),
|
||||
repo: s.repo.clone(), auth: s.auth.clone(), creds: s.creds.clone(),
|
||||
instructions: s.instructions.clone(),
|
||||
};
|
||||
if let Ok(j) = serde_json::to_string_pretty(&snap) { std::fs::write(session_path(), j).ok(); }
|
||||
}
|
||||
fn load_session(s: &mut Session) -> bool {
|
||||
let Ok(txt) = std::fs::read_to_string(session_path()) else { return false };
|
||||
let Ok(snap) = serde_json::from_str::<Snapshot>(&txt) else { return false };
|
||||
if !snap.models.is_empty() { s.models = snap.models; }
|
||||
s.subscription = snap.subscription; s.mcp = snap.mcp;
|
||||
if snap.vote_n > 0 { s.vote_n = snap.vote_n; }
|
||||
s.max_agents = snap.max_agents;
|
||||
s.target = snap.target; s.repo = snap.repo; s.auth = snap.auth;
|
||||
s.creds = snap.creds; s.instructions = snap.instructions;
|
||||
true
|
||||
}
|
||||
|
||||
fn pick<'a>(history: &'a [RunRecord], arg: &str) -> Option<&'a RunRecord> {
|
||||
if history.is_empty() { println!(" no runs yet — /run first."); return None; }
|
||||
if arg.trim().is_empty() { return history.last(); }
|
||||
|
||||
@@ -24,11 +24,13 @@ pub struct Library {
|
||||
pub recon: Vec<Agent>,
|
||||
pub code: Vec<Agent>,
|
||||
pub infra: Vec<Agent>,
|
||||
pub chains: Vec<Agent>,
|
||||
}
|
||||
|
||||
impl Library {
|
||||
pub fn total(&self) -> usize {
|
||||
self.vulns.len() + self.meta.len() + self.recon.len() + self.code.len() + self.infra.len()
|
||||
self.vulns.len() + self.meta.len() + self.recon.len() + self.code.len()
|
||||
+ self.infra.len() + self.chains.len()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +43,7 @@ pub fn load(base: &Path) -> Library {
|
||||
recon: load_dir(&root.join("recon"), "recon"),
|
||||
code: load_dir(&root.join("code"), "code"),
|
||||
infra: load_dir(&root.join("infra"), "infra"),
|
||||
chains: load_dir(&root.join("chains"), "chain"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ pub async fn run(cfg: RunConfig, lib: &Library, pool: &ModelPool, tx: Sender<Str
|
||||
let mut findings = validate(candidates, pool, VOTE_SYS, cfg.vote_n, &tx).await;
|
||||
|
||||
// ---- 5. Chain confirmed findings into deeper impact ----------------
|
||||
let chained = chain_round(pool, &cfg.target, &recon, &operator_directives(&cfg), &findings, &tx).await;
|
||||
let chained = chain_round(pool, &cfg.target, &recon, &operator_directives(&cfg), &findings, &lib.chains, &tx).await;
|
||||
if !chained.is_empty() {
|
||||
let extra = validate(dedup_findings(chained), pool, VOTE_SYS, cfg.vote_n, &tx).await;
|
||||
let _ = tx.send(format!("chaining added {} validated finding(s)", extra.len())).await;
|
||||
@@ -409,7 +409,7 @@ pub async fn run_greybox(cfg: RunConfig, lib: &Library, pool: &ModelPool, tx: Se
|
||||
let candidates = dedup_findings(raw.iter().flat_map(|(_, _, f)| f.clone()).collect());
|
||||
let _ = tx.send(format!("{} candidate finding(s) (deduped) — validating", candidates.len())).await;
|
||||
let mut findings = validate(candidates, pool, VOTE_SYS, cfg.vote_n, &tx).await;
|
||||
let chained = chain_round(pool, &cfg.target, &recon, &operator_directives(&cfg), &findings, &tx).await;
|
||||
let chained = chain_round(pool, &cfg.target, &recon, &operator_directives(&cfg), &findings, &lib.chains, &tx).await;
|
||||
if !chained.is_empty() {
|
||||
let extra = validate(dedup_findings(chained), pool, VOTE_SYS, cfg.vote_n, &tx).await;
|
||||
let _ = tx.send(format!("chaining added {} validated finding(s)", extra.len())).await;
|
||||
@@ -425,19 +425,23 @@ const CHAIN_SYS: &str = "You are an exploit-chaining specialist. Given already-C
|
||||
/// into higher-impact follow-ups, reusing the recon/auth context. Returns the
|
||||
/// (unvalidated) new candidate findings produced by chaining.
|
||||
async fn chain_round(pool: &ModelPool, target: &str, recon: &str, directives: &str,
|
||||
confirmed: &[Finding], tx: &Sender<String>) -> Vec<Finding> {
|
||||
confirmed: &[Finding], chains: &[Agent], tx: &Sender<String>) -> Vec<Finding> {
|
||||
if confirmed.is_empty() {
|
||||
return vec![];
|
||||
}
|
||||
let summary: String = confirmed.iter().take(20)
|
||||
.map(|f| format!("- [{}] {} @ {} ({})", f.severity, f.title, f.endpoint, f.cwe))
|
||||
.collect::<Vec<_>>().join("\n");
|
||||
// Offer the known chain recipes as a menu so the LLM applies proven multi-stage paths.
|
||||
let recipes: String = chains.iter().map(|a| format!("- {}", a.title.replace(" Agent", ""))).collect::<Vec<_>>().join("\n");
|
||||
let recipe_block = if recipes.is_empty() { String::new() } else { format!("KNOWN CHAIN RECIPES (apply any that fit):\n{recipes}\n\n") };
|
||||
let _ = tx.send(format!("chaining {} confirmed finding(s) for deeper impact…", confirmed.len())).await;
|
||||
let recon_ctx: String = recon.chars().take(2500).collect();
|
||||
let user = format!(
|
||||
"AUTHORIZED engagement on {target}.\n\n{directives}{react}{doctrine}\
|
||||
"AUTHORIZED engagement on {target}.\n\n{directives}{react}{doctrine}{recipe_block}\
|
||||
CONFIRMED FINDINGS TO CHAIN:\n{summary}\n\nRecon:\n{recon_ctx}\n\n\
|
||||
Chain these into deeper impact and PROVE it. Reply ONLY a JSON array of NEW findings \
|
||||
Chain these into deeper impact (e.g. SQLi→RCE→LPE, SSRF→cloud creds, upload→LFI→RCE) and PROVE each stage. \
|
||||
Reply ONLY a JSON array of NEW findings \
|
||||
(may be []): {{id,title,severity,cwe,endpoint,payload,evidence,impact,remediation,confidence}}.",
|
||||
react = REACT_DOCTRINE, doctrine = tool_doctrine(pool.mcp_config.is_some()),
|
||||
);
|
||||
@@ -951,7 +955,7 @@ pub async fn run_host(cfg: RunConfig, lib: &Library, pool: &ModelPool, tx: Sende
|
||||
let candidates = dedup_findings(raw.iter().flat_map(|(_, _, f)| f.clone()).collect());
|
||||
let _ = tx.send(format!("{} candidate finding(s) (deduped) — validating", candidates.len())).await;
|
||||
let mut findings = validate(candidates, pool, VOTE_SYS, cfg.vote_n, &tx).await;
|
||||
let chained = chain_round(pool, &cfg.target, &recon, &operator_directives(&cfg), &findings, &tx).await;
|
||||
let chained = chain_round(pool, &cfg.target, &recon, &operator_directives(&cfg), &findings, &lib.chains, &tx).await;
|
||||
if !chained.is_empty() {
|
||||
let extra = validate(dedup_findings(chained), pool, VOTE_SYS, cfg.vote_n, &tx).await;
|
||||
findings.extend(extra);
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
NeuroSploit v3.5.1 — attack-chain agents.
|
||||
|
||||
Each agent is a multi-stage exploitation-chaining playbook: take a confirmed
|
||||
entry-point weakness and escalate it through concrete stages to deeper impact
|
||||
(e.g. SQLi → RCE → local privilege escalation). Writes agents_md/chains/*.md.
|
||||
Credits: Joas A Santos & Red Team Leaders.
|
||||
"""
|
||||
import os
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
OUT = os.path.join(ROOT, "agents_md", "chains")
|
||||
|
||||
|
||||
def render(a):
|
||||
L = [f"# {a['title']} Agent\n", "## User Prompt",
|
||||
f"You are executing a multi-stage ATTACK CHAIN against **{{target}}**: {a['chain']}.\n",
|
||||
"**Recon Context / prior findings:**\n{recon_json}\n",
|
||||
f"**GOAL:** {a['goal']}\n",
|
||||
"**CHAIN — advance stage by stage; each stage's output is the next stage's input. "
|
||||
"Use the ReAct loop and PROVE every stage with raw tool output before advancing:**\n"]
|
||||
for i, (stage, bs) in enumerate(a["stages"], 1):
|
||||
L.append(f"### Stage {i}. {stage}")
|
||||
L += [f"- {b}" for b in bs]
|
||||
L.append("")
|
||||
n = len(a["stages"]) + 1
|
||||
L += [f"### {n}. Report Format",
|
||||
"Report the chain as ONE finding (plus per-stage evidence):", "```", "FINDING:",
|
||||
f"- Title: {a['title']}", f"- Severity: {a['sev']}", f"- CWE: {a['cwe']}",
|
||||
"- Endpoint: [entry point]", "- Vector: [the full chain, stage by stage]",
|
||||
"- Payload: [the key payloads/commands per stage]",
|
||||
"- Evidence: [raw output proving EACH stage actually executed]",
|
||||
f"- Impact: {a['impact']}", f"- Remediation: {a['fix']}",
|
||||
"- chains_from: [ids of the prerequisite findings this builds on]", "```\n",
|
||||
"## System Prompt", a["system"]]
|
||||
return "\n".join(L) + "\n"
|
||||
|
||||
|
||||
def A(name, title, chain, goal, cwe, sev, impact, fix, stages):
|
||||
return {"name": name, "title": title, "chain": chain, "goal": goal, "cwe": cwe,
|
||||
"sev": sev, "impact": impact, "fix": fix, "stages": stages,
|
||||
"system": ("You are an exploit-chaining specialist. Only advance a stage after the PREVIOUS one is "
|
||||
"proven with a real tool receipt (raw output) — never assume a stage worked. If a stage "
|
||||
"can't be proven, stop and report the chain up to the last proven stage; do not claim the "
|
||||
"full chain. AUTHORIZED engagement; no destructive/DoS actions. Each reported stage must "
|
||||
"carry its own evidence. Credits: Joas A Santos & Red Team Leaders.")}
|
||||
|
||||
|
||||
CHAINS = [
|
||||
A("chain_sqli_to_rce_to_lpe",
|
||||
"SQLi → RCE → Local PrivEsc Chain",
|
||||
"SQL injection → command execution → local privilege escalation",
|
||||
"Turn a database-layer injection into root/SYSTEM on the host.",
|
||||
"CWE-89", "Critical",
|
||||
"Full host compromise originating from a web injection",
|
||||
"Parameterize queries; least-privilege DB account; harden host; patch local vectors",
|
||||
[("Exploit the SQL injection", ["Confirm injection (error/boolean/time); identify DBMS and privileges",
|
||||
"Enumerate whether stacked queries / FILE / xp_cmdshell / INTO OUTFILE are available"]),
|
||||
("Pivot SQLi → RCE", ["MSSQL: enable & use `xp_cmdshell`; MySQL: `INTO OUTFILE` a webshell to a known web path; PostgreSQL: `COPY ... PROGRAM`",
|
||||
"Confirm OS command execution with `id`/`whoami` output"]),
|
||||
("Establish a foothold", ["Drop/upgrade to a stable shell as the web/db service user"]),
|
||||
("Local privilege escalation", ["Enumerate SUID/sudo/cron/kernel (Linux) or token/service/unquoted-path (Windows)",
|
||||
"Escalate to root/SYSTEM and prove with a privileged command output"])]),
|
||||
A("chain_ssrf_to_aws_compromise",
|
||||
"SSRF → AWS Credential Compromise Chain",
|
||||
"SSRF → cloud metadata → IAM credentials → cloud account access",
|
||||
"Convert a server-side request forgery into valid AWS credentials and account access.",
|
||||
"CWE-918", "Critical",
|
||||
"Cloud account compromise via stolen IAM role credentials",
|
||||
"Enforce IMDSv2 hop-limit=1; egress allowlists; SSRF input validation; scoped IAM roles",
|
||||
[("Confirm the SSRF primitive", ["Find a server-side fetch you control (url/webhook/import/pdf/image param)",
|
||||
"Prove it reaches an attacker-controlled / internal host"]),
|
||||
("Reach the metadata service", ["IMDSv2: PUT `/latest/api/token` then GET with the token header; else IMDSv1 GET",
|
||||
"Retrieve `/latest/meta-data/iam/security-credentials/<role>`"]),
|
||||
("Harvest IAM credentials", ["Capture AccessKeyId/SecretAccessKey/Token from the metadata response"]),
|
||||
("Use the credentials (in scope)", ["`aws sts get-caller-identity` to confirm; enumerate permitted actions read-only",
|
||||
"Prove access to at least one resource the role can reach"])]),
|
||||
A("chain_ssrf_to_rce",
|
||||
"SSRF → RCE Chain",
|
||||
"SSRF → internal service abuse → remote code execution",
|
||||
"Escalate an SSRF into code execution via a reachable internal service.",
|
||||
"CWE-918", "Critical",
|
||||
"Remote code execution pivoted through an internal service",
|
||||
"Egress controls; authenticate internal services; SSRF allowlists",
|
||||
[("Confirm SSRF + map internals", ["Prove the SSRF; port-scan internal hosts through it (gopher/http)",
|
||||
"Identify exploitable internal services (Redis, unauth admin, CI, internal API)"]),
|
||||
("Weaponize the internal service", ["e.g. Redis → write SSH key/cron/module; internal Jenkins/Actuator → job/exec; gopher:// to craft raw protocol payloads"]),
|
||||
("Achieve RCE", ["Trigger command execution on the internal/back-end host"]),
|
||||
("Confirm", ["Prove execution with an OOB callback or command output tied to a unique marker"])]),
|
||||
A("chain_upload_to_rce",
|
||||
"File Upload → RCE Chain",
|
||||
"insecure file upload → webshell → remote code execution",
|
||||
"Turn an unrestricted/insecure upload into code execution.",
|
||||
"CWE-434", "Critical",
|
||||
"Remote code execution via uploaded executable content",
|
||||
"Validate type by content; randomize names; store outside webroot; non-exec storage",
|
||||
[("Probe the upload", ["Map accepted types/extensions, storage path, and how files are served",
|
||||
"Test bypasses: double extension, content-type spoof, magic-byte prefix, null byte, .htaccess/.phar"]),
|
||||
("Upload a payload", ["Place a minimal webshell/handler in a web-served, executable location"]),
|
||||
("Locate & trigger", ["Find the served URL of the upload; request it to execute"]),
|
||||
("Confirm RCE", ["Run `id`/`whoami`; capture output proving execution"])]),
|
||||
A("chain_upload_lfi_rce_lpe",
|
||||
"Upload → LFI → RCE → LPE Chain",
|
||||
"file upload + local file inclusion → log/session poisoning → RCE → privilege escalation",
|
||||
"Chain a benign upload and an LFI into code execution and then root.",
|
||||
"CWE-98", "Critical",
|
||||
"Host compromise from a non-executable upload chained through LFI",
|
||||
"Fix LFI (allowlist includes); validate uploads; harden host",
|
||||
[("Confirm the LFI", ["Prove local file inclusion (read /etc/passwd or app config); identify wrappers (php://, data://, zip://)"]),
|
||||
("Plant controllable content via upload", ["Upload a file whose path/content you can later include (image with PHP, zip for zip:// , or use the LFI to read your uploaded file)"]),
|
||||
("LFI → RCE", ["Include the planted file, or poison logs/session/`/proc/self/environ` then include it to execute code"]),
|
||||
("Confirm RCE then escalate", ["Prove command execution; then enumerate and perform local privilege escalation to root/SYSTEM"])]),
|
||||
A("chain_xss_to_account_takeover",
|
||||
"XSS → Session/Account Takeover Chain",
|
||||
"stored/reflected XSS → session or token theft → account takeover",
|
||||
"Escalate XSS into full takeover of a victim (incl. admin) account.",
|
||||
"CWE-79", "High",
|
||||
"Account takeover (incl. privileged) via client-side execution",
|
||||
"Output encoding + CSP; HttpOnly/SameSite cookies; rotate tokens",
|
||||
[("Prove execution", ["Confirm the payload executes in the victim's browser context (Playwright: alert/DOM), not just reflects"]),
|
||||
("Steal the session", ["Exfiltrate the session cookie/JWT/CSRF token to a collaborator, or perform actions in-context if HttpOnly"]),
|
||||
("Take over the account", ["Replay the stolen session, or change email/password/MFA via in-context requests"]),
|
||||
("Confirm + escalate", ["Prove control of the victim account; target an admin for privilege escalation"])]),
|
||||
A("chain_idor_to_takeover",
|
||||
"IDOR → Mass Account Takeover Chain",
|
||||
"IDOR → cross-account data → credential/role manipulation → takeover",
|
||||
"Chain object-level authz failure into taking over arbitrary accounts.",
|
||||
"CWE-639", "High",
|
||||
"Mass account takeover via broken object-level authorization",
|
||||
"Enforce per-object ownership on every endpoint; indirect references",
|
||||
[("Confirm the IDOR", ["Access another user's object with your session, proven by their data"]),
|
||||
("Find a state-changing IDOR", ["Locate IDOR on email/password/role/API-key endpoints"]),
|
||||
("Manipulate the victim account", ["Change a victim's email or reset token / elevate role via the IDOR"]),
|
||||
("Confirm takeover", ["Log in as / act as the victim; demonstrate control"])]),
|
||||
A("chain_ssti_to_rce_to_cloud",
|
||||
"SSTI → RCE → Cloud Pivot Chain",
|
||||
"template injection → RCE → host creds → cloud/lateral movement",
|
||||
"Go from template injection to code execution to cloud or lateral access.",
|
||||
"CWE-1336", "Critical",
|
||||
"Cloud/lateral compromise originating from template injection",
|
||||
"Never render user input as templates; sandbox; scope host IAM/creds",
|
||||
[("Confirm SSTI → RCE", ["Fingerprint the engine (`{{7*7}}` etc.); use the gadget to execute a command; prove with output"]),
|
||||
("Loot the host", ["Read env/config/instance metadata for cloud creds, DB creds, tokens"]),
|
||||
("Pivot", ["Use recovered creds against cloud APIs or adjacent internal hosts"]),
|
||||
("Confirm impact", ["Prove access to a cloud resource or a second host with evidence"])]),
|
||||
A("chain_default_creds_to_domain",
|
||||
"Default Creds → Foothold → Domain Compromise Chain",
|
||||
"default/weak creds → host foothold → AD escalation → domain dominance",
|
||||
"Chain an exposed credential into Active Directory domain compromise.",
|
||||
"CWE-798", "Critical",
|
||||
"Domain compromise from a single weak/default credential",
|
||||
"Rotate defaults; unique strong passwords; tiered admin; monitor",
|
||||
[("Get the foothold", ["Authenticate with the default/weak/reused credential (SSH/WinRM/SMB/web)"]),
|
||||
("Enumerate AD", ["From the foothold, run BloodHound/netexec; map attack paths, roastable accounts, ACLs"]),
|
||||
("Escalate in AD", ["Kerberoast/AS-REP-roast, abuse an ACL edge, or relay — recover higher-priv creds"]),
|
||||
("Reach domain dominance", ["Demonstrate DCSync or DA-equivalent access (single test account) proving the path"])]),
|
||||
A("chain_deserialization_to_rce",
|
||||
"Insecure Deserialization → RCE Chain",
|
||||
"untrusted deserialization → gadget chain → remote code execution",
|
||||
"Turn a deserialization sink into reliable code execution.",
|
||||
"CWE-502", "Critical",
|
||||
"Remote code execution via unsafe object deserialization",
|
||||
"Never deserialize untrusted data; allowlist types; safe formats",
|
||||
[("Locate the sink", ["Identify where attacker data is deserialized (cookie/param/file/RPC); fingerprint the format/library"]),
|
||||
("Build the gadget", ["Select a working gadget chain (ysoserial/ysoserial.net/PyYAML/pickle) for the target stack"]),
|
||||
("Execute", ["Deliver the payload to the sink"]),
|
||||
("Confirm", ["Prove execution via OOB callback or command output with a unique marker"])]),
|
||||
A("chain_exposed_git_to_rce",
|
||||
"Exposed .git/.env → Secret → RCE Chain",
|
||||
"exposed source/secrets → recovered credentials → authenticated RCE",
|
||||
"Chain leaked source/secrets into authenticated code execution.",
|
||||
"CWE-527", "High",
|
||||
"Code execution using credentials recovered from exposed source/secrets",
|
||||
"Block dotfiles from web; rotate leaked secrets; vault storage",
|
||||
[("Recover the source/secrets", ["Dump exposed `.git` (git-dumper) or read `.env`/config; extract keys/creds/tokens"]),
|
||||
("Validate the secrets", ["Confirm a recovered credential/key is live (admin panel, cloud, DB, CI)"]),
|
||||
("Gain execution", ["Use the access to deploy code / run a CI job / write a webshell / exec via admin feature"]),
|
||||
("Confirm RCE", ["Prove command execution with output"])]),
|
||||
A("chain_subdomain_takeover_to_phishing",
|
||||
"Subdomain Takeover → Trusted Phishing/Cookie Chain",
|
||||
"dangling DNS → subdomain takeover → trusted-origin abuse",
|
||||
"Chain a dangling record into hosting attacker content on a trusted subdomain.",
|
||||
"CWE-350", "High",
|
||||
"Trusted-origin abuse (cookie theft / phishing / OAuth) via a taken-over subdomain",
|
||||
"Remove dangling DNS; monitor; scope cookies/CSP per-host",
|
||||
[("Find the dangling record", ["Identify a CNAME/A pointing to an unclaimed provider resource"]),
|
||||
("Claim it", ["Register the resource so the subdomain serves your content (benign PoC)"]),
|
||||
("Abuse the trust", ["Show impact: wildcard-cookie capture, OAuth redirect trust, or CSP allowlist bypass"]),
|
||||
("Confirm", ["Demonstrate the concrete trusted-origin abuse with evidence"])]),
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
os.makedirs(OUT, exist_ok=True)
|
||||
for a in CHAINS:
|
||||
open(os.path.join(OUT, a["name"] + ".md"), "w").write(render(a))
|
||||
print(f"wrote {len(CHAINS)} chain agents to {OUT}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user