Over the Wire Bandit walkthrough

So this is the beginner over the wire game. I still consider myself a beginner at this sort of stuff, so I was proud when I was able to complete this without any help. Still, I am writing this to help others that may not be at that level yet. I know when I get stuck on problems, I get super frustrated. Although I am the type of person that will work and work until I can solve it, others might not be able to do that. There may even be some people that like to read walkthroughs to get an understanding of how other people are able to work through the problems. I'm not going to explain how every command works. If you want to know, look at how I used it and use the man pages to figure out what all the flags are for.
Here we go to complete the overthewire game Bandit. You can find this at http://overthewire.org/wargames/bandit

Bandit 0:

Bandit0 gives us a simple username and password to log in with SSH. One tip I would like to add, is that I made a variable in the shell "level" and set it equal to "bandit0". To log in with ssh, I type

$ ssh $level@bandit.labs.overthewire.org.
With this, I am able to just edit the last character of the level each time I need to login, rather than move through the entire SSH command. So, with the ssh command shown above, we are able to log in to bandit0. Bandit 0 -> Bandit 1: Moving from bandit 0 to bandit 1 is pretty easy. There is a readme file in bandit 0's home directory. We can get the password with
bandit0@melinda:~$ cat readme 

Bandit 1 -> Bandit 2:

Once you log in to bandit 1, you will notice a file on the desktop named '-'. Since the dash in bash is a special character, we can't just type

bandit1@melinda:~$ cat -

So, we have to specify that the file name is actually dash in the directory we are in.

bandit1@melinda:~$ cat ./-

And we have the password.

Bandit 2 -> Bandit 3:

Logging in with the password we just got, we see that there is a file with spaces in the name. I easily accomplished this by typing

bandit2@melinda:~$ cat spaces\ in\ this\ filename 

Now, when I first completed this, I just typed $ cat s and it filled in the rest. But, the backslashes mean that you are escaping the spaces so they are interpreted as being in the name.

Bandit 3 -> Bandit 4:

There is a folder called inhere, that appears blank at the first glance. However, typing $ ls -la shows that there is a hidden file called .hidden containing the key.

bandit3@melinda:~$ ls
bandit3@melinda:~$ cd inhere/
bandit3@melinda:~/inhere$ ls -la
total 12
drwxr-xr-x 2 root    root    4096 Jun  6  2013 .
drwxr-xr-x 3 root    root    4096 Jun  6  2013 ..
-rw-r----- 1 bandit4 bandit3   33 Jun  6  2013 .hidden
bandit3@melinda:~/inhere$ cat .hidden 

Bandit 4 -> Bandit 5:

Here we have a folder called inhere, and a few files inside. The page says the password is in the only human readable file, so with the file command we can see that -file07 is the only file with ASCII text.

bandit4@melinda:~$ cd inhere/
bandit4@melinda:~/inhere$ file ./*
./-file00: data
./-file01: data
./-file02: Non-ISO extended-ASCII text, with no line terminators
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: Non-ISO extended-ASCII text
bandit4@melinda:~/inhere$ cat ./-file07

Bandit 5 -> Bandit 6:

We have a folder with a bunch of folders inside, with a bunch of files inside each folder. They told us the file containing the password is 1033 bytes, so we can use the find command to find a file of a specific size.

bandit5@melinda:~$ cd inhere/
bandit5@melinda:~/inhere$ find ./ -type f -size 1033c
bandit5@melinda:~/inhere$ cat ./maybehere07/.file2

Bandit 6 -> Bandit 7:

This time we don't have any files in the home directory. The file is located somewhere on the server with the user bandit7 and the group bandit6. It is also 33 bytes in size. Again we can use the find command to complete this.

bandit6@melinda:~$ find / -type f -user bandit7 -group bandit6 -size 33c 2>/dev/null
bandit6@melinda:~$ cat /var/lib/dpkg/info/bandit7.password

Bandit 7 -> Bandit 8:
There is a file called data.txt in the home directory. It is a huge file that we need to parse through. The password is located next to the word millionth, so we can simply use cat and grep.

bandit7@melinda:~$ ls          
bandit7@melinda:~$ cat data.txt | grep millionth
millionth    cvX2JJa4CFALtqS87jk27qwqGhBM9plV

Bandit 8 -> Bandit 9:
The password is found on the only unique line in the file data.txt. We can use sort and uniq to find that line.

bandit8@melinda:~$ sort data.txt | uniq -u

Bandit 9 -> Bandit 10:

The file data.txt is a binary file this time. We can't easily grep through it, however we can first use strings then grep through. The website says the password is on one of the only lines beginning with an equal sign.

bandit9@melinda:~$ strings data.txt | grep =
========== the
,========== passwordc
========== is
========== truKLdjsbJ5g7yyJ2X2R0o3a5HQJFuLk

Bandit 10 -> Bandit 11:
The password is encoded with base64 inside the file data.txt. We can decode this with the base64 command.

bandit10@melinda:~$ base64 -d data.txt 
The password is IFukwKGsFW8MOq3IRFqrxE1hxTNEbUPR

Bandit 11 -> Bandit 12:
Here we have the password in data.txt where the text has been rotated 13 letters. Using the tr command we are able to reverse this.

bandit11@melinda:~$ cat data.txt | tr '[A-Za-z]' '[N-ZA-Mn-za-m]'
The password is 5Te8Y4drgCRfCx8ugdwuEX8KFC6k2EUu

Bandit 12 -> Bandit 13:
This one was very tedious. Not sure if there is a better way to do this, but I made a directory in /tmp and manually ran file and decompressed accordingly. Very slow and boring, but here is the whole excerpt of what I did.

bandit12@melinda:~$ mkdir /tmp/zer0w1re
bandit12@melinda:~$ cd /tmp/zer0w1re
bandit12@melinda:/tmp/zer0w1re$ cat ~/data.txt | xxd -r > ./data
bandit12@melinda:/tmp/zer0w1re$ file data 
data: gzip compressed data, was "data2.bin", from Unix, last modified: Thu Jun  6 13:59:44 2013, max compression
bandit12@melinda:/tmp/zer0w1re$ mv data{,.gz}
bandit12@melinda:/tmp/zer0w1re$ gunzip data.gz 
bandit12@melinda:/tmp/zer0w1re$ file data 
data: bzip2 compressed data, block size = 900k
bandit12@melinda:/tmp/zer0w1re$ mv data{,.bz2}
bandit12@melinda:/tmp/zer0w1re$ bzip2 -d data.bz2 
bandit12@melinda:/tmp/zer0w1re$ file data 
data: gzip compressed data, was "data4.bin", from Unix, last modified: Thu Jun  6 13:59:43 2013, max compression
bandit12@melinda:/tmp/zer0w1re$ mv data{,.gz}
bandit12@melinda:/tmp/zer0w1re$ gunzip data.gz 
bandit12@melinda:/tmp/zer0w1re$ file data 
data: POSIX tar archive (GNU)
bandit12@melinda:/tmp/zer0w1re$ tar xvf data 
bandit12@melinda:/tmp/zer0w1re$ file data5.bin 
data5.bin: POSIX tar archive (GNU)
bandit12@melinda:/tmp/zer0w1re$ tar xvf data5.bin 
bandit12@melinda:/tmp/zer0w1re$ file data6.bin 
data6.bin: bzip2 compressed data, block size = 900k
bandit12@melinda:/tmp/zer0w1re$ mv data6{.bin,.bz2}
bandit12@melinda:/tmp/zer0w1re$ bzip2 -d data6.bz2 
bandit12@melinda:/tmp/zer0w1re$ ls
data5.bin  data6
bandit12@melinda:/tmp/zer0w1re$ file data6
data6: POSIX tar archive (GNU)
bandit12@melinda:/tmp/zer0w1re$ tar xvf data6 
bandit12@melinda:/tmp/zer0w1re$ file data8.bin 
data8.bin: gzip compressed data, was "data9.bin", from Unix, last modified: Thu Jun  6 13:59:43 2013, max compression
bandit12@melinda:/tmp/zer0w1re$ mv data8{.bin,.gz} 
bandit12@melinda:/tmp/zer0w1re$ gunzip data8.gz 
bandit12@melinda:/tmp/zer0w1re$ ls
data5.bin  data6  data8
bandit12@melinda:/tmp/zer0w1re$ file data8
data8: ASCII text
bandit12@melinda:/tmp/zer0w1re$ cat data8 
The password is 8ZjyCRiBWFYkneahHwxCv3wb2a1ORpYL

Bandit 13 -> Bandit 14:
This was very simple. When you login to bandit13, you immediately see a private SSH key in the home directory. Copy that to your computer, and specify to use the key with the command

ssh bandit14@bandit.labs.overthewire.com -i ~/Desktop/id_rsa

and you will get access to bandit14.

Bandit 14 -> Bandit 15:
For this one, all we need to do is submit our current password to the server on port 30000. Since we logged in using an SSH private key, we do not immediately know the password. However, we have read permissions to our password in /etc/bandit_pass. So we can simply use

bandit14@melinda:~$ echo `cat /etc/bandit_pass/bandit14` | nc localhost 30000

Bandit 15 -> Bandit 16:

Here we need to do pretty much the same thing as the last level, except we need to use SSL. Running the command

bandit15@melinda:~$ echo `cat /etc/bandit_pass/bandit15` | openssl s_client -connect localhost:30001       
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1
Certificate chain
 0 s:/CN=localhost
Server certificate
No client certificate CA names sent
SSL handshake has read 1272 bytes and written 375 bytes
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
    Protocol  : SSLv3
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 39D149A21A2A56D90DC51A0BE4EBC9888DD3DB16A8645BB4D3C6B12B53B8795A
    Master-Key: 4ED46FF6D414DE2C0AFD0283521A5141FBBB0D8048924E6AE31C6C65053F5ABB35B27F8D61775FE6F01DC3F084E1F7DA
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1406837006
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)

Gives us something, but not the password. As we can see, towards the end it says "HEARTBEATING" which on the OTW page it says to use the -quiet flag if it does that. I do, and it gives us the password.

bandit15@melinda:~$ echo `cat /etc/bandit_pass/bandit15` | openssl s_client -connect localhost:30001 -quiet
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1


Bandit 16 -> Bandit 17:
Here they give us a range of ports, 31000-32000. One port is using SSL and will give us the next password if we send our current one. Running nmap we get this:

bandit16@melinda:~$ nmap -p31000-32000 localhost -sV

Starting Nmap 5.21 ( http://nmap.org ) at 2014-07-31 20:13 UTC
Nmap scan report for localhost (
Host is up (0.00076s latency).
Not shown: 995 closed ports
31000/tcp open  ssh     OpenSSH 5.9p1 Debian 5ubuntu1.4 (protocol 2.0)
31046/tcp open  echo
31518/tcp open  msdtc   Microsoft Distributed Transaction Coordinator (error)
31691/tcp open  echo
31790/tcp open  msdtc   Microsoft Distributed Transaction Coordinator (error)
31960/tcp open  echo
Service Info: OSs: Linux, Windows

Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 41.19 seconds

Right off the bat, 31000, 31046, 31691, and 31960 are out, since those are echo or SSH. 31518 and 31790 are possible, so we will just try both of them.
31518 doesn't give us anything back

bandit16@melinda:~$ echo `cat /etc/bandit_pass/bandit16` | openssl s_client -connect localhost:31518 -quiet
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1

so it must be 31790

bandit16@melinda:~$ echo `cat /etc/bandit_pass/bandit16` | openssl s_client -connect localhost:31790 -quiet
depth=0 CN = localhost
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = localhost
verify return:1


Hey! We got another RSA private key!

Bandit 17 -> Bandit 18:
We are given two files, password.old and password.new. The new password is the only line different between to two, so we can use diff to find it.

bandit17@melinda:~$ diff passwords.old passwords.new 

The second one is the password.

Bandit 18 -> Bandit 19:
Someone has modified .bashrc to immediately log you out when you try to login. Bummer.

ssh bandit18@bandit.labs.overthewire.org
Byebye !
Connection to bandit.labs.overthewire.org closed.

The password is stored in ~/readme. We can run commands as we login, however. So running

ssh $level@bandit.labs.overthewire.org -t 'command; cat readme'
bandit18@bandit.labs.overthewire.org's password: 
Connection to bandit.labs.overthewire.org closed.

will give us the password!

Bandit 19 -> Bandit 20:

Here they give us a SUID binary. Not sure what it does so we can run it and see the usage. We try running a command and it works so lets just try catting the password. Bingo.

bandit19@melinda:~$ ls
bandit19@melinda:~$ ./bandit20-do 
Run a command as another user.
  Example: ./bandit20-do id
bandit19@melinda:~$ ./bandit20-do 0
env: 0: No such file or directory
bandit19@melinda:~$ ./bandit20-do cat  

bandit19@melinda:~$ ./bandit20-do cat /etc/bandit_pass/bandit2
cat: /etc/bandit_pass/bandit2: Permission denied
bandit19@melinda:~$ ./bandit20-do cat /etc/bandit_pass/bandit20

Bandit 20 -> Bandit 21:
This one required a little bit of thinking. We login and there is a file 'suconnect'. It makes a connection to localhost on the port you specify as a commandline argument. It then reads a line of text from the connection and compares it to the password in the previous level (bandit20). If the password is correct, it will transmit the password for the next level (bandit21). All we need to do is run nc listening on a random port, then connect to it with suconnect. Then we send the password of bandit20 through the nc session and suconnect sends back the new password. Simple!
First we start the nc session.

bandit20@melinda:~$ nc -l 12345

Then we connect with suconnect in a different window.

bandit20@melinda:~$ ./suconnect 12345

Then back in the nc window we send our current password and suconnect will send back the new password.

bandit20@melinda:~$ nc -l 12345
bandit20@melinda:~$ ./suconnect 12345
Read: GbKksEFF4yrVs6il55v6gwY5aVje5f0j
Password matches, sending next password

Bandit 21 -> Bandit 22:
There is a cron job that we need to look at. In /etc/cron.d there are a bunch of files, but cronjob_bandit22 looks like what we need.

bandit21@melinda:/etc/cron.d$ ll
total 128
drwxr-xr-x   2 root root 4096 Jul 22 13:40 ./
drwxr-xr-x 109 root root 4096 Jul 31 13:19 ../
-rw-r--r--   1 root root  102 Apr  2  2012 .placeholder
-rw-r--r--   1 root root   52 Oct 22  2013 boobiesbot-check
-rw-r--r--   1 root root  355 Nov 18  2011 cron-apt
-rw-r--r--   1 root root   61 Jun  6  2013 cronjob_bandit22
-rw-r--r--   1 root root   62 Jun  6  2013 cronjob_bandit23
-rw-r--r--   1 root root   61 Jun  6  2013 cronjob_bandit24
-rw-r--r--   1 root root   35 Jun  6  2013 eloi0
-rw-r--r--   1 root root   35 Jun  6  2013 eloi1
-rw-r--r--   1 root root   49 Jul  3 14:13 hintbot-check
-rw-------   1 root root  233 Jun  6  2013 manpage3_resetpw_job
-rw-r--r--   1 root root   51 Jul 12 15:57 melinda-stats
-rw-r--r--   1 root root   54 Sep 30  2013 natas-session-toucher
-rw-r--r--   1 root root   49 Sep 30  2013 natas-stats
-r--r-----   1 root root   47 Sep 30  2013 natas25_cleanup
-r--r-----   1 root root   45 Jul 22 13:40 natas26_cleanup
-rw-r--r--   1 root root  544 Mar 11  2013 php5
-rw-r--r--   1 root root   58 Jun  6  2013 semtex0-32
-rw-r--r--   1 root root   58 Jun  6  2013 semtex0-64
-rw-r--r--   1 root root   59 Jun  6  2013 semtex0-ppc
-rw-r--r--   1 root root   36 Jun  6  2013 semtex10
-rw-r--r--   1 root root  143 Jun  6  2013 semtex12
-rw-r--r--   1 root root   35 Jun  6  2013 semtex5
-rw-r--r--   1 root root   29 Jun  6  2013 semtex6
-rw-r--r--   1 root root   96 Jun  6  2013 semtex8
-rw-r--r--   1 root root  134 Jun  6  2013 semtex9
-rw-r--r--   1 root root  396 Dec 16  2011 sysstat
-rw-r--r--   1 root root   29 Jun  6  2013 vortex0
-rw-r--r--   1 root root   30 Jul  2  2013 vortex20
-rw-r--r--   1 root root   52 Jul  3 13:41 vulnbot0-check
-rw-r--r--   1 root root   52 Jul  3 13:41 vulnbot1-check
bandit21@melinda:/etc/cron.d$ cat cronjob_bandit22 
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null

We see that it is calling /usr/bin/cronjob_bandit22.sh.

bandit21@melinda:/etc/cron.d$ cat /usr/bin/cronjob_bandit22.sh 
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
bandit21@melinda:/etc/cron.d$ cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv

Theres the password.

Bandit 22 -> Bandit 23:
Another cron job is being called.

bandit22@melinda:~$ cat /etc/cron.d/cronjob_bandit23 
* * * * * bandit23 /usr/bin/cronjob_bandit23.sh  &> /dev/null
bandit22@melinda:~$ cat /usr/bin/cronjob_bandit23.sh 

mytarget=$(echo I am user $myname | md5sum | cut -d ' ' -f 1)

echo "Copying passwordfile /etc/bandit_pass/$myname to /tmp/$mytarget"

cat /etc/bandit_pass/$myname > /tmp/$mytarget

We can see that it has a static name that is being called, so lets figure it out.

bandit22@melinda:~$ echo I am user bandit23 | md5sum | cut -d ' ' -f 1
bandit22@melinda:~$ cat /tmp/8ca319486bfbbc3663ea0fbe81326349

And there's our password!

Bandit 23 -> Bandit 24:
Last problem! For this one, we need to create our own shell script to run. I created a directory /tmp/zw and made my script called "gimmepassword.sh". This will cat the bandit password and pipe it to another file, /tmp/zww. We just needed to make sure it had rwx permissions and that it was copied to /var/spool/bandit24.

bandit23@melinda:/tmp/zw$ cat gimmepassword.sh 

cat /etc/bandit_pass/bandit24 > /tmp/zww

bandit23@melinda:/tmp/zw$ chmod 777 gimmepassword.sh 
bandit23@melinda:/tmp/zw$ cp gimmepassword.sh /var/spool/bandit24/
bandit23@melinda:/tmp/zw$ cat /tmp/zww

And there we have the password for the final level! Maybe they will make level 25 in the future, but until then, we're on to a different game!