Jason Turley's Website

OverTheWire: Bandit Writeup

Bandit is a wargame from overthewire.org focused on teaching beginners the necessary skills to play other wargames. It covers essential Linux commands such as grep, find, and ssh. The later levels cover more advanced Linux topics like cronjobs and writing shell scripts.

This post contains my solutions. The password flags have been redacted and replaced with a series of x’s. I am still working through the later levels, and will update this post accordingly.

Level 0

Level Goal

The goal of this level is for you to log into the game using SSH. The host to which you need to connect is bandit.labs.overthewire.org, on port 2220. The username is bandit0 and the password is bandit0. Once logged in, go to the Level 1 page to find out how to beat Level 1.

Solution

ssh bandit0@bandit.labs.overthewire.org -p 2220

Level 0 –> Level 1

Level Goal

The password for the next level is stored in a file called readme located in the home directory. Use this password to log into bandit1 using SSH. Whenever you find a password for a level, use SSH (on port 2220) to log into that level and continue the game.

Solution

Simply print out the contents of the readme file.

bandit0@bandit:~$ ls
readme
bandit0@bandit:~$ cat readme
XXXXXXXXXXXXX

Level 1 –> 2

Level Goal

The password for the next level is stored in a file called - located in the home directory

Solution

This level is tricky because a dash (-) represents standard input or output. To get around this, specify the full file path with ./

bandit1@bandit:~$ cat ./-
XXXXXXXXXX

Level 2 –> 3

Level Goal

The password for the next level is stored in a file called spaces in this filename located in the home directory.

Solution

I utilized tab auto-completion to print out the file.

bandit2@bandit:~$ cat spaces\ in\ this\ filename
XXXXXXXX
bandit2@bandit:~$

Level 3 –> 4

Level Goal

The password for the next level is stored in a hidden file in the inhere directory.

Solution

Use ls -A to view the hidden file and print out the contents.

bandit3@bandit:~$ ls
inhere
bandit3@bandit:~$ cd inhere/
bandit3@bandit:~/inhere$ ls -A
.hidden
bandit3@bandit:~/inhere$ cat .hidden
XXXXXXXX
bandit3@bandit:~/inhere$

Level 4 –> 5

Level Goal

The password for the next level is stored in the only human-readable file in the inhere directory. Tip: if your terminal is messed up, try the “reset” command.

Solution

The goal is to find the only human-readable file. In this case, that means the only ASCII text file. I used the file command to get the type of each file, and printed the ASCII one.

bandit4@bandit:~/inhere$ file ./-file0*
./-file00: data
./-file01: data
./-file02: data
./-file03: data
./-file04: data
./-file05: data
./-file06: data
./-file07: ASCII text
./-file08: data
./-file09: data
bandit4@bandit:~/inhere$ cat ./-file07
XXXXXXXXX

Level 5 –> 6

Level Goal

The password for the next level is stored in a file somewhere under the inhere directory and has all of the following properties:

Solution

bandit5@bandit:~/inhere$ find . -size 1033c ! -executable
./maybehere07/.file2
bandit5@bandit:~/inhere$ cat ./maybehere07/.file2
XXXXXX

Let’s break this command down:

Level 6 –> 7

Level Goal

The password for the next level is stored somewhere on the server and has all of the following properties:

Solution

Again, we can use the almighty find command:

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

Bonus: alternatively, I piped the output of find into the xargs command to print it in one line:

bandit6@bandit:~$ find / -user bandit7 -group bandit6 -size 33c 2>/dev/null | xargs cat
XXXXXXX

Level 7 –> 8

Level Goal

The password for the next level is stored in the file data.txt next to the word millionth

Solution

Used grep to search for the word millionth.

bandit7@bandit:~$ grep "millionth" data.txt
millionth       XXXXXX

Level 8 –> 9

Level Goal

The password for the next level is stored in the file data.txt and is the only line of text that occurs only once

Solution

The data file contains a ton of duplicate lines of text. My solution was to sort the file, and then print the only unique line of text.

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

Level 9 –> 10

Level Goal

The password for the next level is stored in the file data.txt in one of the few human-readable strings, preceded by several ‘=’ characters.

Solution

The strings command prints human-readable strings from binary data.

bandit9@bandit:~$ strings -20 data.txt
&========== XXX

Level 10 –> 11

Level Goal

The password for the next level is stored in the file data.txt, which contains base64 encoded data

Solution

The data is base64 encoded, so I decoded it with base64 -d

bandit10@bandit:~$ base64 -d data.txt
The password is XXXXXXX
bandit10@bandit:~$

Level 11 –> 12

Level Goal

The password for the next level is stored in the file data.txt, where all lowercase (a-z) and uppercase (A-Z) letters have been rotated by 13 positions

Solution

I used the translate command to map upper case A-Z to N-ZA-M and lower case a-z to n-za-m. This effectively rotates all the letters over by 13 positions.

bandit11@bandit:~$ cat data.txt | tr A-Za-z N-ZA-Mn-za-m
The password is xxxxxx

Level 12 –> 13

Level Goal

The password for the next level is stored in the file data.txt, which is a hexdump of a file that has been repeatedly compressed. For this level it may be useful to create a directory under /tmp in which you can work using mkdir. For example: mkdir /tmp/myname123. Then copy the datafile using cp, and rename it using mv (read the manpages!)

Solution

This level was annoying. It requires you to unzip/decompress the data file with xxd -r, gunzip, bunzip2, and tar -xf several times. I had to do it roughly 8 times.

Level 13 –> 14

Level Goal

The password for the next level is stored in /etc/bandit_pass/bandit14 and can only be read by user bandit14. For this level, you don’t get the next password, but you get a private SSH key that can be used to log into the next level. Note: localhost is a hostname that refers to the machine you are working on

Solution

In the home directory there is a private SSH key. This can be used in place of a password to login in as bandit14. I used scp (ssh copy) to transfer the file from the remote server to my local laptop:

jason@lapras:~$ scp -P 2220 bandit13@bandit.labs.overthewire.org:sshkey.private .
This is a OverTheWire game server. More information on http://www.overthewire.org/wargames

bandit13@bandit.labs.overthewire.org's password:
sshkey.private                                                                                                    100% 1679    10.6KB/s   00:00

When trying to use the private SSH key, I got an error saying that permissions 0640 are too open. 0640 means that the owner can read/write to the file, and group users can read the file. I used chmod to make it so only the file owner can read/write to the file.

jason@lapras:~$ chmod 0600 sshkey.private
jason@lapras:~$ ls -l sshkey.private
-rw------- 1 jason jason 1679 Oct 18 21:38 sshkey.private

Finally, we can SSH with the private key instead of providing a password:

jason@lapras:~$ ssh bandit14@bandit.labs.overthewire.org -p 2220 -i sshkey.private

Level 14 –> 15

Level Goal

The password for the next level can be retrieved by submitting the password of the current level to port 30000 on localhost.

Solution

The previous level stated that the password is stored in /etc/bandit_pass/bandit14. Next, the password needs to be submitted on localhost over port 30000. I used telnet for this.

telnet 127.0.0.1 30000
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
4wcYUJFw0k0XLShlDzztnTBHiqxU3b3e
Correct!
xxxxxxxxxxxxxxxxxxxxxxxxx

Connection closed by foreign host.
bandit14@bandit:~$

Level 15 –> 16

Level Goal

The password for the next level can be retrieved by submitting the password of the current level to port 30001 on localhost using SSL encryption.

Solution

This level is nearly identical to the previous one. The main different being that this one request using SSL encryption (aka secure transmission). This means we will not be able to use telnet! Instead, I used the openssl command:

bandit15@bandit:~$ openssl s_client -connect 127.0.0.1:30001

Level 16 –> 17

Level Goal

The credentials for the next level can be retrieved by submitting the password of the current level to a port on localhost in the range 31000 to 32000. First find out which of these ports have a server listening on them. Then find out which of those speak SSL and which don’t. There is only 1 server that will give the next credentials, the others will simply send back to you whatever you send to it.

Solution

We need to find the one server that is using SSL between ports 31000 and 32000. The nmap (Network Mapper) tool is great for scanning open ports and finding running services. When I ran my nmap scan, I found two SSL servers. However, one of them was an echo server - so it just repeated my messages back to me.

bandit16@bandit:~$ nmap -sV -p31000-32000 127.0.0.1

Starting Nmap 7.40 ( https://nmap.org ) at 2020-10-19 05:02 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00025s latency).
Not shown: 995 closed ports
PORT      STATE SERVICE     VERSION
31046/tcp open  echo
31337/tcp open  Elite?
31518/tcp open  ssl/echo
            <----- echoes back messages!
31691/tcp open  echo
31790/tcp open  ssl/unknown
         <----- use this one!
31960/tcp open  echo

Now for the openssl command:

bandit16@bandit:~$ openssl s_client -connect 127.0.0.1:31790

Once the password is entered, we are awarded another private ssh key.

Level 17 –> 18

Level Goal

There are 2 files in the homedirectory: passwords.old and passwords.new. The password for the next level is in passwords.new and is the only line that has been changed between passwords.old and passwords.new

Solution

I used the diff command to view what was different between the 2 files.

bandit17@bandit:~$ diff passwords.new passwords.old
42c42
< xxxxxxx
---
> w0Yfolrc5bwjS4qw5mq1nnQi6mF03bii  <--- not the password

Level 18 –> 19

Level Goal

The password for the next level is stored in a file readme in the homedirectory. Unfortunately, someone has modified .bashrc to log you out when you log in with SSH.

Solution

Since we automatically logged out when using SSH, I used scp to copy the readme file to my local work station.

jason@lapras:~$ scp -P 2220 bandit18@bandit.labs.overthewire.org:readme .
This is a OverTheWire game server. More information on http://www.overthewire.org/wargames

bandit18@bandit.labs.overthewire.org's password:
readme
jason@lapras:~$ cat readme
XXxxXXX

Level 19 –> 20

Level Goal

To gain access to the next level, you should use the setuid binary in the homedirectory. Execute it without arguments to find out how to use it. The password for this level can be found in the usual place (/etc/bandit_pass), after you have used the setuid binary.

Solution

A setuid binary essentially allows you to run the binary as another user . In this case, that is bandit20. We can use it to print the password for bandit20.

bandit19@bandit:~$ ./bandit20-do cat /etc/bandit_pass/bandit20
XXXXX

Level 20 –> 21

Level Goal

There is a setuid binary in the homedirectory that does the following: 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).

NOTE: Try connecting to your own network daemon to see if it works as you think

Solution

For this level I used netcat to create a listening server for the setuid binary to connect to. To manage two terminals, I used tmux.

First, set up the listening server:

bandit20@bandit:~$ nc -nvlp 8888
listening on [any] 8888 ...

Next, run the binary:

bandit20@bandit:~$ ./suconnect 8888

Observe the output:

bandit20@bandit:~$ nc -nvlp 8888
listening on [any] 8888 ...
connect to [127.0.0.1] from (UNKNOWN) [127.0.0.1] 42132
xxxxxxxxxxxxxxxxxxxxx <--- enter bandit19 password here
aaaaaaaaaaaaaaaaaaaaa <--- receive bandit20 password here
bandit20@bandit:~$

Level 21 –> 22

Level Goal

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

Solution

Looking in the /etc/cron.d/ folder, we see a file called cronjob_bandit22. A cronjob is just a program that is scheduled to run in the background. Let’s look inside it:

bandit21@bandit:~$ cat /etc/cron.d/cronjob_bandit22
@reboot bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null
* * * * * bandit22 /usr/bin/cronjob_bandit22.sh &> /dev/null

We see a shell script called /usr/bin/cronjob_bandit22.sh. Let’s look inside that:

bandit21@bandit:~$ cat /usr/bin/cronjob_bandit22.sh
#!/bin/bash
chmod 644 /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
cat /etc/bandit_pass/bandit22 > /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv

Ok, so it writes bandit22’s password to a file in the /tmp directory. Simply print that file.

bandit21@bandit:~$ cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
xxxx

Level 22 –> 23

Level Goal

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

NOTE: Looking at shell scripts written by other people is a very useful skill. The script for this level is intentionally made easy to read. If you are having problems understanding what it does, try executing it to see the debug information it prints.

Solution

Similarly to the previous challenge, there is a cronjob that calls a shell script.

bandit22@bandit:~$ cat /usr/bin/cronjob_bandit23.sh
#!/bin/bash

myname=$(whoami)
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

When we run this script as bandit22, we get our password written to a unique file in /tmp. What would happen if we were to change the $myname variable to bandit23 in the 4th line of the script?

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

Level 23 –> 24

Level Goal

A program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed.

NOTE: This level requires you to create your own first shell-script. This is a very big step and you should be proud of yourself when you beat this level!

NOTE 2: Keep in mind that your shell script is removed once executed, so you may want to keep a copy around…

Solution