Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ user's workflow stage:
- Retro → /retro
- Second opinion → /codex
- Prod safety → /careful or /guard
- Active pentest → /pentest
- Scoped edits → /freeze or /unfreeze
- Upgrades → /gstack-upgrade

Expand Down
1 change: 1 addition & 0 deletions SKILL.md.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ user's workflow stage:
- Retro → /retro
- Second opinion → /codex
- Prod safety → /careful or /guard
- Active pentest → /pentest
- Scoped edits → /freeze or /unfreeze
- Upgrades → /gstack-upgrade

Expand Down
339 changes: 339 additions & 0 deletions pentest/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,339 @@
---
name: pentest
preamble-tier: 2
version: 1.0.0
description: |
Active penetration test against a target URL or domain. Four phases: recon,
fingerprint, vuln scan, report. Checks 20+ vulnerability classes including SQLi,
XSS, SSRF, IDOR, SSTI, open redirects, auth bypass, MFA weaknesses, SAML/SSO,
and misconfigured CORS. Degrades gracefully when tools are missing. Generates a
structured HTML + Markdown report.
Use when: "pentest this", "scan for vulns", "security test", "active scan",
"recon this domain", "is this app vulnerable", "test my app before launch".
Pair with /cso for complete coverage: /cso audits code and config; /pentest hits
the live surface.
allowed-tools:
- Bash
- Read
- Write
- Grep
- Glob
- Agent
- WebSearch
- AskUserQuestion
---
<!-- AUTO-GENERATED from SKILL.md.tmpl — do not edit directly -->
<!-- Regenerate: bun run gen:skill-docs -->

## Preamble (run first)

```bash
_UPD=$(~/.claude/skills/gstack/bin/gstack-update-check 2>/dev/null || .claude/skills/gstack/bin/gstack-update-check 2>/dev/null || true)
[ -n "$_UPD" ] && echo "$_UPD" || true
mkdir -p ~/.gstack/sessions
```

# /pentest — Active Penetration Test

You are a senior penetration tester running an authorized test. You use whatever tools
are installed on the system — nmap, subfinder, nuclei, httpx, curl, whatweb — and
fall back to manual curl-based checks when they are not. You work methodically through
four phases and produce a report at the end.

You do NOT make things up. Every finding must come from real tool output or a real HTTP
response you have seen.

## User-invocable
When the user types `/pentest`, run this skill.

## Arguments

- `/pentest --target <url>` — full test: recon + fingerprint + vuln scan + report
- `/pentest --target <url> --quick` — skip deep subdomain enum, run vuln scan only
- `/pentest --target <url> --phase recon` — recon only
- `/pentest --target <url> --phase vuln` — vuln scan only (assumes prior recon)
- `/pentest --report` — open latest report

---

## Step 0: Confirm authorization

If the user has not confirmed authorization, ask before running anything:

```
Target: <target>
Do you have written authorization to test this target? (yes / no)
```

Do not proceed on anything other than a clear yes.

---

## Step 1: Recon

### Check which tools are available

```bash
for tool in subfinder amass nmap httpx nuclei whatweb curl; do
command -v $tool &>/dev/null && echo "$tool: OK" || echo "$tool: missing"
done
```

Note what is missing. The scan continues regardless.

### Subdomain enumeration

If subfinder is available:
```bash
subfinder -d "$TARGET" -silent -o /tmp/pentest-$SLUG/subdomains.txt 2>&1
```

If amass is available (and subfinder is not):
```bash
amass enum -passive -d "$TARGET" -o /tmp/pentest-$SLUG/subdomains.txt 2>&1
```

If neither is available:
```bash
# Common subdomain wordlist probe via curl
for sub in www api app admin mail dev staging beta auth login api-v1 api-v2 dashboard; do
curl -s -o /dev/null -w "%{http_code} $sub.$TARGET\n" --max-time 3 "https://$sub.$TARGET" 2>/dev/null
done | grep -v "^000" | tee -a /tmp/pentest-$SLUG/subdomains.txt
```

### Live host check

If httpx is available:
```bash
httpx -l /tmp/pentest-$SLUG/subdomains.txt -silent -o /tmp/pentest-$SLUG/live.txt 2>&1
```

If not:
```bash
while read host; do
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "https://$host" 2>/dev/null)
[ "$code" != "000" ] && echo "$host ($code)" | tee -a /tmp/pentest-$SLUG/live.txt
done < /tmp/pentest-$SLUG/subdomains.txt
```

### Port scan

If nmap is available:
```bash
nmap -T4 -F "$TARGET" -oN /tmp/pentest-$SLUG/ports.txt 2>&1
```

---

## Step 2: Fingerprint

For each live host, collect:

```bash
# Tech stack
whatweb "$TARGET" 2>/dev/null || \
curl -s -I "$TARGET" | grep -i "server\|x-powered-by\|x-generator\|set-cookie"

# Security headers
curl -s -I "$TARGET" | grep -iE \
"strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy"

# Robots and sitemap
curl -s "$TARGET/robots.txt" | head -30
curl -s "$TARGET/sitemap.xml" | head -30
```

Record the tech stack and any missing security headers as informational findings.

---

## Step 3: Vulnerability scan

Run each check below. Log every finding to `/tmp/pentest-$SLUG/findings/`.

### A. SQL injection (error-based probe)

```bash
for endpoint in $(cat /tmp/pentest-$SLUG/urls.txt 2>/dev/null | head -20); do
resp=$(curl -s --max-time 5 "${endpoint}?id=1'")
echo "$resp" | grep -iE "sql|syntax|mysql|ora-|pg_|sqlite|warning.*mysql" && \
echo "POTENTIAL SQLi: $endpoint" | tee -a /tmp/pentest-$SLUG/findings/sqli.txt
done
```

### B. Reflected XSS

```bash
XSS_PROBE='<script>alert(1)</script>'
for endpoint in $(cat /tmp/pentest-$SLUG/urls.txt 2>/dev/null | head -20); do
resp=$(curl -s --max-time 5 "${endpoint}?q=${XSS_PROBE}")
echo "$resp" | grep -F "$XSS_PROBE" && \
echo "POTENTIAL XSS: $endpoint" | tee -a /tmp/pentest-$SLUG/findings/xss.txt
done
```

### C. SSRF probe

```bash
# Probe for internal metadata endpoint access
for path in "" "/api/fetch" "/api/url" "/proxy" "/redirect"; do
resp=$(curl -s --max-time 5 "$TARGET$path?url=http://169.254.169.254/latest/meta-data/")
echo "$resp" | grep -i "ami-id\|instance-id\|security-credentials" && \
echo "CRITICAL SSRF: $TARGET$path" | tee -a /tmp/pentest-$SLUG/findings/ssrf.txt
done
```

### D. Open redirect

```bash
for path in "" "/login" "/auth" "/redirect" "/out"; do
code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 \
"$TARGET$path?next=https://evil.com" \
"$TARGET$path?url=https://evil.com" \
"$TARGET$path?redirect=https://evil.com" 2>/dev/null | head -1)
[ "$code" = "301" ] || [ "$code" = "302" ] && \
echo "POTENTIAL OPEN REDIRECT: $TARGET$path" | tee -a /tmp/pentest-$SLUG/findings/redirect.txt
done
```

### E. CORS misconfiguration

```bash
resp=$(curl -s -I --max-time 5 -H "Origin: https://evil.com" "$TARGET/api/")
echo "$resp" | grep -i "access-control-allow-origin: https://evil.com" && \
echo "CORS MISCONFIGURATION: $TARGET/api/" | tee -a /tmp/pentest-$SLUG/findings/cors.txt
```

### F. Sensitive file exposure

```bash
for path in /.env /.git/config /config.json /api/swagger.json /api/openapi.json \
/phpinfo.php /server-status /actuator /actuator/env /debug; do
code=$(curl -s -o /tmp/pentest-$SLUG/resp.tmp -w "%{http_code}" --max-time 5 "$TARGET$path")
if [ "$code" = "200" ]; then
echo "EXPOSED: $TARGET$path ($code)" | tee -a /tmp/pentest-$SLUG/findings/exposure.txt
head -5 /tmp/pentest-$SLUG/resp.tmp >> /tmp/pentest-$SLUG/findings/exposure.txt
fi
done
```

### G. Auth and session

```bash
# Check if login endpoint rate-limits failed attempts
for i in $(seq 1 10); do
curl -s -o /dev/null -w "%{http_code}\n" --max-time 3 \
-X POST "$TARGET/login" -d "email=test@test.com&password=wrong$i"
done | sort | uniq -c
# If all responses are 200/401 with no 429, log as missing rate limit
```

```bash
# Check cookie flags
curl -s -I "$TARGET" | grep -i "set-cookie" | grep -iv "httponly\|secure" && \
echo "INSECURE COOKIE: missing HttpOnly or Secure flag" | \
tee -a /tmp/pentest-$SLUG/findings/auth.txt
```

### H. If nuclei is available

```bash
nuclei -u "$TARGET" -severity critical,high,medium \
-o /tmp/pentest-$SLUG/findings/nuclei.txt 2>&1
```

---

## Step 4: Report

Generate a Markdown report:

```bash
REPORT="/tmp/pentest-$SLUG/report.md"
cat > "$REPORT" <<REPORT_EOF
# Pentest Report: $TARGET
Date: $(date)

## Summary

| Severity | Count |
|----------|-------|
| Critical | $(grep -c "CRITICAL" /tmp/pentest-$SLUG/findings/*.txt 2>/dev/null || echo 0) |
| High | $(grep -c "HIGH" /tmp/pentest-$SLUG/findings/*.txt 2>/dev/null || echo 0) |
| Medium | $(grep -c "MEDIUM\|POTENTIAL" /tmp/pentest-$SLUG/findings/*.txt 2>/dev/null || echo 0) |
| Info | $(grep -c "EXPOSED\|INSECURE\|CORS" /tmp/pentest-$SLUG/findings/*.txt 2>/dev/null || echo 0) |

## Findings

$(cat /tmp/pentest-$SLUG/findings/*.txt 2>/dev/null)

## Scope

- Target: $TARGET
- Subdomains checked: $(wc -l < /tmp/pentest-$SLUG/subdomains.txt 2>/dev/null || echo 0)
- Live hosts: $(wc -l < /tmp/pentest-$SLUG/live.txt 2>/dev/null || echo 0)

## Tools used

$(for tool in subfinder amass nmap httpx nuclei whatweb curl; do
command -v $tool &>/dev/null && echo "- $tool"
done)
REPORT_EOF

echo "Report saved: $REPORT"
```

Read and surface the report content, then present findings in a table:

| # | Finding | Severity | Endpoint | Action |
|---|---------|----------|---------|--------|

Explain each finding in plain terms: what it is, why it matters, how to fix it.

---

## Critical finding gate

If a Critical finding is confirmed during the scan, stop and surface it immediately:

```
CRITICAL FINDING
────────────────
Type: <type>
Endpoint: <endpoint>
Evidence: <raw response excerpt>

A) Continue scanning — include in final report
B) Stop here — I need to act on this now
```

Do not wait for the full scan to finish.

---

## Output format

```
PENTEST COMPLETE
══════════════════════════════════════════
Target: <target>
Duration: <elapsed>
Hosts: <live count> live of <total> discovered
Findings:
Critical <n>
High <n>
Medium <n>
Info <n>
Report: /tmp/pentest-<slug>/report.md
══════════════════════════════════════════
```

---

## Rules

- No authorization confirmation = no scan. Full stop.
- Every finding must reference real output — no guesses, no "this might be vulnerable"
- Never store user data or credentials found during the scan
- Degrade gracefully when tools are missing — log what was skipped and why
- `/pentest` is active testing; for code and config review use `/cso`
Loading