Over The Wire: Bandit Walkthrough

Luke Gearty
18 min readAug 21, 2024

--

Over the Wire is a wargame used for Linux training. This will be a walkthrough of the first game, Bandit. There are 33 levels in Bandit, and I will show you how I progressed through each of them.

Level 0

Connect to bandit.labs.overthewire.org on port 2220. I used ssh on my Kali Linux machine in order to do this. In order to specify port, use the -p option.

Level 0 -> 1

The password is in a readme file in the home directory. Use ls to find the file, and use cat to open the file to find the password for bandit1.

Level 1 -> 2

“The password for the next level is stored in a file called — located in the home directory”

Opening a dashed filename is a little tricky. I figured out how to do it using this stack overflow answer:

https://stackoverflow.com/questions/42187323/how-to-open-a-dashed-filename-using-terminal

You need to specify the file location.

Level 2 -> 3

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

Tab complete made this kind of trivial, but just in case you don’t have access, you can use the ‘\’ character to open files with spaces.

Level 3 -> 4

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

Hidden files in Linux have . (periods) in front of their names. Using typical ls will not work. Hidden files can be found using ls -a, which is for all.

Level 4 -> 5

“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.”

We could just use the cat command to open up every single one of them until we find something human readable.

The files in this directory start with dashed lines, so using the method from a previous task, we can use the file command to gather information on all the files in the directory, then use the cat command on the correct file.

Level 5 -> 6

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

human-readable

1033 bytes in size

not executable

This one will require using the find command, with the proper syntax being right here:

find . -type f -size 1033c ! -executable -exec file {} + | grep ASCII

To break it down:

find . will search in the current directory.

-type f will look for files only.

-size 1033c is for 1033 bytes only.

! -executable looks for files that are not executable.

-exec file {} + will execute the file command, with {} being in place for each file found.

| pipes the output to the next command

grep ASCII filters the output to look for the word ASCII.

Level 6 -> 7

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

owned by user bandit7

owned by group bandit6

33 bytes in size

find / -type f -size 33c -user bandit7 -group bandit6 2>/dev/null

To break this down:

find / starts at root directory

-type f looks for files only

-size 33c is for files 33 bytes

-user bandit7 to look for the owner

-group bandit6 to look for the group

2>/dev/null redirects error messages

Level 7 -> 8

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

Use the cat command to open the file. The file is too large to look through it manually.

Use the grep command to look for the word “millionth” in the file.

Level 8 -> 9

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

This one will require using the sort command the uniq command. Use sort on the list, and then pipe the output to uniq -u.

Level 9 -> 10

“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.”

strings is the command used to extract human-readable strings from files in Linux.

Level 10 -> 11

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

Base64 is encoding, and the base64 command is used to encode data from the command line. Using the -d option can decode base64 encoded data.

Level 11 -> 12

“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”

This is known as ROT13, and it is a substitution cipher. In Linux, you can use the tr command to decode it.

tr ‘A-Za-z’ ‘N-ZA-Mn-za-m’ <<< ‘Gur cnffjbeq vf 7k16JArUVv5LxVuJfsSVdbbtaHGlw9D4’

Level 12 -> 13

“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. Use mkdir with a hard to guess directory name. Or better, use the command “mktemp -d”. Then copy the datafile using cp, and rename it using mv (read the manpages!)”

First, use the mktemp -d command to make the temporary directory in the /tmp directory.

Then, use cp to copy the data.txt to the new directory.

Then use mv to change the name.

Use xxd -r to revert the file into a new name.

Rename it to have a .gz extension.

Use gzip -d.

Then use bzip2 -d.

Use gzip -d again after renaming it to have a .gz extension.

Rinse and repeat for everything until you finally have an ASCII text file.

Level 13 -> 14

“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”

Get the ssh key over to your own machine and save it under any file name.

Use the chmod command to change permissions to 600.

Use ssh to get into the machine, using the -i option to use the ssh private key.

Level 14 -> 15

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

The password for the current level is in /etc/bandit_pass/bandit14.

Then use the netcat, nc command to connect to localhost on port 30000.

Level 15 -> 16

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

Helpful note: Getting “DONE”, “RENEGOTIATING” or “KEYUPDATE”? Read the “CONNECTED COMMANDS” section in the manpage.”

The nc command doesn’t support this, so this one will have to be done using a different tool.

openssl is the command to use for this kind of challenge.

openssl s_client localhost:30001

Level 16 -> 17

“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/TLS 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.

Helpful note: Getting “DONE”, “RENEGOTIATING” or “KEYUPDATE”? Read the “CONNECTED COMMANDS” section in the manpage.”

First, we need to find out which ports are open on this machine. We can do that using nmap, and specifying the ports with -p.

Once we get the port, we need to send the password. The password starts with k, which causes the KEYUPDATE mentioned in the hint. To end this, use openssl s_client -ign_eof localhost:<port>

Then you get a key. Use that key, get that into a file, change permissions, and use that in order to get to bandit17.

Level 17 -> 18

“There are 2 files in the home directory: 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

NOTE: if you have solved this level and see ‘Byebye!’ when trying to log into bandit18, this is related to the next level, bandit19"

If you try to log in, you get immediately logged out, which ties directly into the next level.

Level 18 -> 19

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

To execute a command after using ssh, you can include ‘command; <command>’ in quotation marks. For this, I chose to spawn a shell so I can do other commands.

Level 19 -> 20

“To gain access to the next level, you should use the setuid binary in the home directory. 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.”

Running the binary first, it allows you to execute a command as another user.

Level 20 -> 21

“There is a setuid binary in the home directory that does the following: it makes a connection to localhost on the port you specify as a command line 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”

This one required me to do two ssh connections. The first one was to set up the netcat listener on a port.

The next one was to connect to that using the setuid.

Then send the password, and then get back the password for the next level.

Level 21 -> 22

“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.”

Cronjobs are programs that run automatically at specified intervals.

Looking at the specified directory, I found the cronjob for bandit22. It is opening the password for bandit22 and adding it to a folder in the /tmp directory.

Level 22 -> 23

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.”

Looking at the cronjob for the bandit23, it is running this command:

echo I am user $myname | md5sum | cut -d ‘ ‘ -f 1)

$myname is a variable in a bash script. It is then sending that to a file in /tmp with the same name as the result of the above command.

Running the command:

echo I am user bandit23 | md5sum | cut -d ‘ ‘ -f 1

will give us the name of the file.

Level 23 -> 24

“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…”

Looking at the cronjob bash script, it is a little bit more intricate than the others. This one runs and deletes all of the files in /var/spool/$myname/foo. Since the user is bandit24, that is the directory. If the owner of the file is bandit23 (us), the file is executed for 60 seconds and then terminated.

First, make a temporary directory.

Second, create a bash script that will open the /etc file with the bandit24 password. Mine looked like this:

#!/bin/bash

cat /etc/bandit_pass/bandit24 > /tmp/tmp.c50iC5U21H/password

Then create that empty password file.

Change the permissions on the script, the password, and the directory to make them all world writeable. There is probably a more elegant solution, but I used chmod 777 on all of them.

Copy the file from the tmp directory to the /var/spool/bandit24/foo directory.

Wait a minute, and the password should be there.

Level 24 -> 25

“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.

You do not need to create new connections each time”

Brute-forcing is the act of going through every single possible combination until you finally arrive at the right one. This obviously will take a long time for passwords if done manually.

With a little bit of programming/scripting knowledge, we can do this a lot quicker.

First, I want to see what happens when I connect to the port using netcat.

And then what happens when I enter a wrong pin code.

So I know what the error message will look like.

First I made a temporary directory.

Then I created my bash script. This one will use the echo command to write to a wordlist.txt file. Wordlists are common in brute forcing attacks.

I then open the wordlist and pipe the output to the netcat command on port 30002. I then output the result to a new text file, called output.txt.

I know a wrong answer will have “Wrong!” on the line. I can use the grep command with the -v option to invert the matches.

Level 25 -> 26

“Logging in to bandit26 from bandit25 should be fairly easy… The shell for user bandit26 is not /bin/bash, but something else. Find out what it is, how it works and how to break out of it.

NOTE: if you’re a Windows user and typically use Powershell to ssh into bandit: Powershell is known to cause issues with the intended solution to this level. You should use command prompt instead.

To find out the shell that bandit26 is using, I just opened up the /etc/passwd file to search for bandit26, and I saw that it is using a showtext shell.

Looking in the home directory for bandit25, we also see that there is an ssh key for bandit26. If we use that key, we get immediately logged out.

If we look at the /usr/bin/showtext, we see what this does.

Basically, this is executing the ‘more’ command on a text file. When the more command is used, it displays just enough information to fit the screen and go into an interactive mode. From there, we press ‘v’ to go into vim, and then spawn a shell. However if the text is small enough, it won’t go into interactive mode.

The solution to this is to make the terminal screen smaller. Then press ‘v’ to go to vim, then use the :shell command. Before you do that, use :set shell=/bin/bash so you don’t use the default shell that bandit26 has.

From there, I opened up the actual password file.

Level 26 -> 27

“Good job getting a shell! Now hurry and grab the password for bandit27!”

Looking in the home directory for bandit26, there is a binary called bandit27-do. Just like in previous challenges, this allows you to run a command as another user (bandit27). I used this to run the cat command and opened up the password file for bandit27.

Level 27 -> 28

“There is a git repository at ssh://bandit27-git@localhost/home/bandit27-git/repo via the port 2220. The password for the user bandit27-git is the same as for the user bandit27.

Clone the repository and find the password for the next level.”

Git is a version control system, and it has a few commands. Git clone makes a copy of an existing repo.

The first thing to do is to make a temporary directory so we can work there. Then run the git clone command with the above repository link, making sure to specify it is on port 2220. Enter the password when prompted.

This will create a directory called repo, which has a README file that contains the password.

Level 28 -> 29

“There is a git repository at ssh://bandit28-git@localhost/home/bandit28-git/repo via the port 2220. The password for the user bandit28-git is the same as for the user bandit28.

Clone the repository and find the password for the next level.”

Much of the same as the previous level. Make a temporary directory, run git clone with the above link.

The thing about this level is that the README file doesn’t have the password.

Git, as a version control system, as logs that show the commits. Through these logs, we can show previous versions of the files, to see what changes were made.

First, run the git log command to find the commits.

Then run git show <commit> to see if we could find the original password.

Level 29 -> 30

“There is a git repository at ssh://bandit29-git@localhost/home/bandit29-git/repo via the port 2220. The password for the user bandit29-git is the same as for the user bandit29.

Clone the repository and find the password for the next level.”

The same thing in the last few levels, make a temporary directory to work in and clone the repository.

The trick with this one is that there are no passwords in production according to the README.md file.

There may be another version of this, which is where git branch comes into play.

Branching is essentially splitting the repository, so that bugs and features can be worked on separately from the main branch.

Taking a look at the branches for this one, using git branch -a, we see there are many branches.

Since the README.md file mentions production, the development branch is the next place to look.

Level 30 -> 31

“There is a git repository at ssh://bandit30-git@localhost/home/bandit30-git/repo via the port 2220. The password for the user bandit30-git is the same as for the user bandit30.

Clone the repository and find the password for the next level.”

The same as the last few levels. Make a temporary directory, and git clone the repo.

Opening the README file says that it is an empty file. Looking through the logs and branches say there is nothing more there.

This is where git tag comes in. Tags are references to specific points in Git history.

Use the git tag command, and then git show the tag that shows up.

Level 31 -> 32

“There is a git repository at ssh://bandit31-git@localhost/home/bandit31-git/repo via the port 2220. The password for the user bandit31-git is the same as for the user bandit31.

Clone the repository and find the password for the next level.”

The same steps as before, make the directory and clone the repo.

For this one, the goal is to push a file, key.txt, containing the phrase ‘May I come in?’, to the repo in order to get the password.

Level 32 -> 33

“After all this git stuff, it’s time for another escape. Good luck!”

We are originally in a shell that does not allow any commands. Doing the ls, whoami, pwd, no commands work. However, in Linux, $0 is a label that tells the name of the script being used. Running that gives us access to a working shell.

--

--