OverTheWire – Bandit Writeup
OverTheWire hosts wargames organized in levels. You need the flag from each level to access the next one. Bandit is the first wargame on the site aimed at beginners.
You can check out the site at https://overthewire.org/wargames/
To follow along with the challenges and their descriptions you can go directly to https://overthewire.org/wargames/bandit/
Level 0
We just need to SSH into the server.
ssh bandit0@bandit.labs.overthewire.org -p 2220
Once there we see a file called readme
. If we read the contents of the file, we get the password for the next level.
Level 1
After we SSH into the level we list the files in the current (home) directory with ls
and we see a file called -
(just the dash symbol). To read this file we run:
cat ./-
Level 2
The file we need to read is called spaces in the filename
. As the name suggests, we need to escape the spaces in the filename. We can do so like this:
cat spaces\ in\ the\ filename
Level 3
The directory inhere
shows no files when we run ls
. We need to make sure to list all files:
ls -la inhere
We see a file called ...Hiding-From-You
which gives us the flag.
cat inhere/...Hiding-From-You
Level 4
To find the only human readable file inside the inhere
directory we can check the file types of all the files:
file inhere/*
We see that file07
is the only one that contains ASCII text.
Level 5
The find
command provides us with all the necessary arguments to find the file.
find inhere/ -type f -readable ! -executable -size 1033c
We find the correct file:
Level 6
We again need to use the find
command with the correct arguments.
find / -type f -size 33c -user bandit7 -group bandit6 2>/dev/null
Level 7
To find the line containing the word millionth
we use grep
:
grep "millionth" data.txt
Level 8
To find the only unique line we first need to sort
the whole file, then print out only unique lines:
sort data.txt | uniq -u
Level 9
To see only human readable lines we use strings
:
strings data.txt
Level 10
We need to decode the base64 encoded file:
base64 -d data.txt
Level 11
We will use tr
to rotate the letters back.
cat data.txt | tr "[A-Za-z]" "[N-ZA-Mn-za-m]"
Level 12
We just need to move the file to a tmp directory, and decompress it. After each decompression we see another format. We keep decompressing every time until we finally get to the flag.
Level 13
We download the private key and use that to log in with SSH.
Level 14
We know where the password is from the previous level so we just redirect it’s output using the netcat
command.
cat /etc/bandit_pass/bandit14 | nc localhost 30000
Level 15
Using openssl
and specifically the s_client
we are able to implement a generict SSL/TLS client to send over the password.
cat /etc/bandit_pass/bandit15 | openssl s_client -connect localhost:30001 -quiet
Level 16
We first use nmap
to check out the open ports. Then we try the same command as last level with all the ports we got, until we finally get the correct response.
We can save this key and use it to connect to bandit17
like we previously did. Save it in a file and use it as the private key. Don’t forget to give it the necessary permissions using chmod 400 filename
.
Level 17
To find out the only line that has changed we use diff
:
diff passwords.old passwords.new
Level 18
To bypass this issue we just pass the command we want to execute to the ssh
command.
ssh bandit18@bandit.labs.overthewire.org -p 2220 "cat readme"
Level 19
The file .bandit20-do
will be ran with the user bandit20
permissions, so we just use it to read the file.
./bandit20-do cat /etc/bandit_pass/bandit20
Level 20
For this one we need to open 2 terminals and connect to bandit20
on both. Once there, we run the following command on terminal 1:
nc -lvnp 4444
netcat
will now be listening on port 4444. On terminal 2 we run the script on the home directory, passing it the port.
./suconnect 4444
Once the connection is made, we just need to write the password of bandit20
on the terminal 1 (where we ran netcat
). We then get the password for the next level on terminal 2.
Level 21
We first check the cron job:
We see that it’s running a bash script. If we read the contents of that script we see where the password is being stores and all that’s left is to read it.
Level 22
We check again the cronjobs and see that it’s running a bash script.
This command is getting the md5 hash of the sentence “I am user bandit23” and creating a tmp directory with it’s name. If we read that dir we get the password:
Level 23
Again there is a bash script being ran regularly through a cronjob:
This script is looking through all the files in /var/spool/bandit24/foo
and checking if the owner is bandit23
(which we are). If it is, it runs the script. So we have to write a script that will let us read the bandit24
password and move it into this directory. It is better to create a temporary directory and write our script there, as there might be complications writing it directly in the home directory (for example if we name our script script.sh
we see that there is already another script.sh
file created by another player.
mkdir /tmp/ssilatel-tmp
vi bandit24pass.sh
This will be the script:
#!/bin/bash
cat /etc/bandit_pass/bandit24 > /tmp/ssilatel/bandit24pass
Don’t forget to give both the script and the directory the necessary permissions:
chmod 777 bandit24pass.sh
chmod 777 /tmp/ssilatel-tmp
cp bandit24pass.sh /var/spool/bandit24/foo/
After this we just have to wait (max. 1 minute) for the cronjob to run the script. If we check again (ls
) in our directory we see the file bandit24pass
created which contains the password.
Level 24
We will need to write a script to brute-force this process. As before, let’s do it in a temporary directory.
mkdir /tmp/ssilatel-24
cd /tmp/ssilatel-24
vi bruteforce.sh
This will be the script:
#!/bin/bash
for i in {0000..9999}
do
echo gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8 $i >> numbers.txt
done
cat numbers.txt | nc localhost 30002 > results.txt
After, we need to give the necessary permissions to the script and run it. We grep
for any lines not containing “Wrong!” and we get our password.
chmod +x bruteforce.sh
./bruteforce.sh
grep -v "Wrong!" results.txt
Level 25
All we need to do here is take the ssh key for bandit26
.
Level 26
If we try to log in using the sshkey we get immediately disconnected.
First we need to login as bandit25
. Through that we are able to see the shell that bandit26
is using, by checking /etc/passwd
.
We see that it uses a script called showtext
that uses the tool more
to open a file called text.txt
.
The trick to getting a shell here is to use more
to enter vim mode. To do this, we need to rescale our terminal window to the smallest possible size, so more
cannot display the whole message and goes into command mode. From there we can press v
to enter vim. Vim allows us to get a shell into the system, but we first have to set the shell to use bash
.
We first run the command :set shell=/bin/bash
.
The we run :shell
.
We see there is a file called bandit27-do
. We’ve seen this before. This script has the SUID set to bandit27
, so it will be run with that user’s permissions. Using this script we can read the password for bandit27
.
./bandit27-do cat /etc/bandit_pass/bandit27
Level 27
We need to use git
to download the repo. We will do this in a temporary directory. This time I opted to use mktemp
which creates the directory for us. The trick is to pass in the correct port number to the command:
bandit27@bandit:~$ mktemp -d
/tmp/tmp.Fe0cOX1Wy9
bandit27@bandit:~$ cd /tmp/tmp.Fe0cox1Wy9
bandit27@bandit:/tmp/tmp.Fe0cOX1Wy9$ git clone ssh://bandit27-git@localhost:2220/home/bandit27-git/repo
This downloads the repo to our directory. If we look inside it only contains a README file which gives us the password.
cat repo/README
Level 28
We repeat the same steps as in level 27 to create a temporary directory and download the git repo to it. We see the repo only has a README.md file in it, with the bandit29 password redacted. If we check the history of the file using git log
, we see that there was a commit with the description “fix info leak”. This can mean that the commit before it contained the plain text password. If we revert to that commit and read the README.md file, we can see the password for the next level.
bandit27@bandit:~$ mktemp -d
/tmp/tmp.Fe0cOX1Wy9
bandit27@bandit:~$ cd /tmp/tmp.Fe0cox1Wy9
bandit27@bandit:/tmp/tmp.Fe0cOX1Wy9$ git clone ssh://bandit28-git@localhost:2220/home/bandit28-git/repo
cd repo
git log README.md
git checkout 73f5d0435070c8922da12177dc93f40b2285e22a .
cat README.md
Level 29
We repeat the same steps as before to download the repo:
bandit27@bandit:~$ mktemp -d
/tmp/tmp.Fe0cOX1Wy9
bandit27@bandit:~$ cd /tmp/tmp.Fe0cox1Wy9
bandit27@bandit:/tmp/tmp.Fe0cOX1Wy9$ git clone ssh://bandit29-git@localhost:2220/home/bandit29-git/repo
If we try to read the README.md file we see that the password is redacted. The message “<no passwords in production!>” could mean there are other branches (such as a development branch) that could contain the password. We look for other branches and switch to the dev one:
If we read the README.md file now, we will see the password for the next level.
Level 30
We repeat the same steps as before to download the repo:
bandit27@bandit:~$ mktemp -d
/tmp/tmp.Fe0cOX1Wy9
bandit27@bandit:~$ cd /tmp/tmp.Fe0cox1Wy9
bandit27@bandit:/tmp/tmp.Fe0cOX1Wy9$ git clone ssh://bandit30-git@localhost:2220/home/bandit30-git/repo
If we check the logs and branches we don’t see anything. Another git feature is tags: they allow for marking points in that git repo’s history. We check for tags:
git tag
We see there is a tag called “secret“. If we read it, we get the password for the next level.
git show secret
Level 31
We repeat the same steps as before to download the repo:
bandit27@bandit:~$ mktemp -d
/tmp/tmp.Fe0cOX1Wy9
bandit27@bandit:~$ cd /tmp/tmp.Fe0cox1Wy9
bandit27@bandit:/tmp/tmp.Fe0cOX1Wy9$ git clone ssh://bandit30-git@localhost:2220/home/bandit30-git/repo
If we read the README file, we see it wants us to push a file to the repo.
echo "May I come in?" > key.txt
git add key.txt
We see that the .gitignore
file doesn’t allow .txt
files, so we have to use the -f
flag to force add our file. After pushing, we get the password.
git add key.txt -f
git commit -m "Give me the password"
git push -u origin master
Level 32
When we log in to bandit32
we are greeted with a message:
WELCOME TO THE UPPERCASE SHELL
This means that all our commands will be in uppercase, which doesn’t let us run our usual commands. The only thing that is uppercase in Linux are variables. Specifically, the variable “$0
” holds a reference to a shell. If we type simply
$0
we see that we get a shell. In here we can list all the files:
ls -la
We see that the uppershell
file runs as with the SUID of bandit33
. This means that we are bandit33
(we can test this by running whoami
). Now that we know this, we can simply read the password:
cat /etc/bandit\_pass/bandit33
Conclusion
At the moment there are no more levels on Bandit. If we SSH into the last level (bandit33
), we can see a README.txt file, which contains a congratulations message for solving every level.
Leave a Reply