Back to Blog

OTW Bandit writeup
October 14, 2024, 12:53 pm

Introduction

The Bandit wargame is an online game provided by the OverTheWire community that teaches various Linux commands and fundamental system features.


This is a brief overview of my solutions for this challenge. I encourage you to attempt it on your own before reviewing my answers, as you won't gain much without trying. My aim here is to demonstrate my approach and allow you to compare your solutions with mine.


Please note that it’s helpful to keep the official website open while reading this write-up, as it contains information about the objectives of each challenge and additional reading resources.


Bandit 00 Solution

To connect, use the following details: the host is bandit.labs.overthewire.org on port 2220, with the username bandit0 and password bandit0. The password for the next level can be found in a file named "readme" located in the home directory.

$ ssh bandit0@bandit.labs.overthewire.org -p 2220
$ ls -la
total 24
drwxr-xr-x  2 root    root    4096 Oct 16 14:00 .
drwxr-xr-x 41 root    root    4096 Oct 16 14:00 ..
-rw-r--r--  1 root    root     220 May 15  2017 .bash_logout
-rw-r--r--  1 root    root    3526 May 15  2017 .bashrc
-rw-r--r--  1 root    root     675 May 15  2017 .profile
-rw-r-----  1 bandit1 bandit0   33 Oct 16 14:00 readme
bandit0@bandit:~$ cat readme
boJ9jbbUNNfktd78OOpsqOltutMc3MY1

Explanation: You simply need to use the cat command to read the contents of the "readme" file.


Bandit 01 Solution

The password for the next level is located in a file named - within the home directory.

$ ssh bandit1@bandit.labs.overthewire.org -p 2220
bandit1@bandit: $ cat ./-
CV1DtqXWVFXTvM2F0k09SHz0YwRINYA9
bandit1@bandit:~$

Explanation: The symbol - indicates reading from stdin in a shell, so you must specify a path to access the file. If you don't provide a path, the cat command will read from stdin and echo your input back.


Bandit 02 Solution

The password for the next level is found in a file named "spaces in this filename," which is located in the home directory.

$ ssh bandit2@bandit.labs.overthewire.org -p 2220
bandit2@bandit:~$ ls
spaces in this filename
bandit2@bandit:~$ cat "spaces in this filename"
UmHadQclWmgdLOKQ3YNgjWxGoRMb5luK

Explanation: You can also read the file by escaping the spaces with backslashes (\), like this: cat spaces\ in\ this\ filename.


Bandit 03 Solution

The password for the next level is located in a hidden file within the "inhere" directory.

$ ssh bandit3@bandit.labs.overthewire.org -p 2220
bandit3@bandit:~$ ls
inhere
bandit3@bandit:~$ cd inhere/
bandit3@bandit:~/inhere$ ls
bandit3@bandit:~/inhere$ ls -la
total 12
drwxr-xr-x 2 root    root    4096 Dec 28 14:34 .
drwxr-xr-x 3 root    root    4096 Dec 28 14:34 ..
-rw-r----- 1 bandit4 bandit3   33 Dec 28 14:34 .hidden
bandit3@bandit:~/inhere$ cat .hidden 
pIwrPrtPN36QITSp3EQaw936yaFoFgAB

Explanation: In Linux, a hidden file is any file that starts with a dot (.). Such files are not visible with the basic ls command. To view hidden files, you must include the -a option with the command.


Bandit 04 Solution

The password for the next level is stored in the only human-readable file in the "inhere" directory.

$ ssh bandit4@bandit.labs.overthewire.org -p 2220
bandit4@bandit:~$ ls
inhere
bandit4@bandit:~$ cd inhere/
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
koReBOKuIDDepwhWk7jZC0RTdopnAYKh

Explanation: In this step, we use the file command along with a wildcard to identify the file that contains only ASCII text.


Bandit 05 Solution

The password for the next level is located in a file somewhere within the "inhere" directory and has the following characteristics:

  • Human-readable
  • 1033 bytes in size
  • Not executable
$ ssh bandit5@bandit.labs.overthewire.org -p 2220
bandit5@bandit:~/inhere$ find ./inhere/ -type f -readable ! -executable -size 1033c
/home/bandit5/inhere/maybehere07/.file2
bandit5@bandit:~/inhere$ cat /home/bandit5/inhere/maybehere07/.file2
DXjZPULLxYr17uwoI01bNLQbtFemEgo7

Explanation: The find command is very helpful for locating specific files. In this case, we used the -readable, ! -executable, and -size 1033c options to identify a file with the specified attributes.


Bandit 06 Solution

The password for the next level is found on the server in a file that meets the following criteria:

  • Owned by user bandit7
  • Owned by group bandit6
  • 33 bytes in size
$ ssh bandit6@bandit.labs.overthewire.org -p 2220
$ find / -type f -size 33c -group bandit6 -user bandit7 2>&1 | grep -v "Permission denied"
/var/lib/dpkg/info/bandit7.password
find: ‘/proc/11148/task/11148/fdinfo/6’: No such file or directory
find: ‘/proc/11148/fdinfo/5’: No such file or directory
bandit6@bandit:~$ cat /var/lib/dpkg/info/bandit7.password
HKBPTKQnIay4Fw76bEy8PVxKEDQRKTzs

Explanation: This is similar to the previous level, except we redirect errors for unreadable files to stderr. We also instruct find to search from the root of the file system since we do not know the exact file location.


Bandit 07 Solution

The password for the next level is stored inside of data.txt, next to the word "millionth."

$ ssh bandit7@bandit.labs.overthewire.org -p 2220
bandit7@bandit:~$ find / -name "data.txt" -exec grep -H 'millionth' {} \; 2>&1 | grep -v "Permission denied"
/home/bandit7/data.txt:millionth	cvX2JJa4CFALtqS87jk27qwqGhBM9plV

Explanation: We use the -exec option of the find command along with grep to locate the file that contains the word "millionth."


Bandit 08 Solution

The password for the next level is inside data.txt, specifically as the only line of text that appears just once.

$ ssh bandit8@bandit.labs.overthewire.org -p 2220
bandit8@bandit:~$ sort data.txt | uniq -c | grep "1 "
      1 UsvVyFSfZZWbi6wgC7dAFyFuR6jQQUhR

Explanation: First, we use sort to organize the contents of data.txt alphabetically, and then we use uniq to count occurrences and identify the line of text that appears only once.


Bandit 09 Solution

The password for the next level is found in data.txt, in one of the few human-readable strings that start with multiple characters.

$ ssh bandit9@bandit.labs.overthewire.org -p 2220
bandit9@bandit:~$ strings data.txt | grep "^=="
========== password
========== isa
========== truKLdjsbJ5g7yyJ2X2R0o3a5HQJFuLk

Explanation: The strings command is used to extract human-readable strings, and then we use grep to filter for strings that begin with several characters.


Bandit 10 Solution

The password for the next level is contained in data.txt, which holds base64-encoded data.

$ ssh bandit10@bandit.labs.overthewire.org -p 2220
bandit10@bandit:~$ ls
data.txt
bandit10@bandit:~$ cat data.txt 
VGhlIHBhc3N3b3JkIGlzIElGdWt3S0dzRlc4TU9xM0lSRnFyeEUxaHhUTkViVVBSCg==
bandit10@bandit:~$ cat data.txt | base64 -d
The password is IFukwKGsFW8MOq3IRFqrxE1hxTNEbUPR

Explanation: We read the contents of data.txt and pipe the output to the base64 command, using the -d option to decode the string.


Bandit 11 Solution

The password for the next level can be found in the file data.txt, where all letters (both lowercase and uppercase) have been rotated by 13 positions.

$ ssh bandit11@bandit.labs.overthewire.org -p 2220
bandit11@bandit:~$ cat data.txt | tr 'A-Za-z' 'N-ZA-Mn-za-m'

The password is 5Te8Y4drgCRfCx8ugdwuEX8KFC6k2EUu.

Explanation: The tr command translates characters from the range A-Z and a-z to their counterparts in a 13-position rotation.


Bandit 12 Solution

The password for the next level is located in data.txt, which contains a hexdump of a file that has been compressed multiple times.

$ ssh bandit12@bandit.labs.overthewire.org -p 2220
# Create a working directory
bandit12@bandit:~$ mkdir /tmp/ax
bandit12@bandit:~$ cp data.txt /tmp/ax
bandit12@bandit:~$ cd /tmp/ax
# Convert the hexdump back to binary
bandit12@bandit:/tmp/ax$ xxd -r data.txt data.out
bandit12@bandit:/tmp/ax$ file data.out
data.out: gzip compressed data, was "data2.bin", last modified: Tue Oct 16 12:00:23 2018, max compression, from Unix
bandit12@bandit:/tmp/ax$ mv data.out data.gz
bandit12@bandit:/tmp/ax$ gzip -d data.gz 
bandit12@bandit:/tmp/ax$ file data
data: bzip2 compressed data, block size = 900k
bandit12@bandit:/tmp/ax$ bzip2 -d data
bzip2: Can't guess original name for data -- using data.out
bandit12@bandit:/tmp/ax$ file data.out
data.out: gzip compressed data, was "data4.bin", last modified: Tue Oct 16 12:00:23 2018, max compression, from Unix
bandit12@bandit:/tmp/ax$ mv data.out data.gz
bandit12@bandit:/tmp/ax$ gzip -d data.gz
bandit12@bandit:/tmp/ax$ file data
data: POSIX tar archive (GNU)
bandit12@bandit:/tmp/ax$ tar -xf data
bandit12@bandit:/tmp/ax$ file data5.bin
data5.bin: POSIX tar archive (GNU)
bandit12@bandit:/tmp/ax$ tar -xf data5.bin
bandit12@bandit:/tmp/ax$ file data6.bin
data6.bin: bzip2 compressed data, block size = 900k
bandit12@bandit:/tmp/ax$ bzip2 -d data6.bin
bzip2: Can't guess original name for data6.bin -- using data6.bin.out
bandit12@bandit:/tmp/ax$ file data6.bin.out
data6.bin.out: POSIX tar archive (GNU)
bandit12@bandit:/tmp/ax$ tar -xf data6.bin.out
bandit12@bandit:/tmp/ax$ file data8.bin
data8.bin: gzip compressed data, was "data9.bin", last modified: Tue Oct 16 12:00:23 2018, max compression, from Unix
bandit12@bandit:/tmp/ax$ mv data8.bin data8.gz
bandit12@bandit:/tmp/ax$ gzip -d data8.gz
# Finally
bandit12@bandit:/tmp/ax$ file data8
data8: ASCII text
bandit12@bandit:/tmp/ax$ cat data8

The password is 8ZjyCRiBWFYkneahHwxCv3wb2a1ORpYL.

Explanation: The -r flag of xxd converts the hexdump back to binary. The file command identifies the compression method used, allowing for recursive decompression.


Bandit 13 Solution

The password for the next level is located in /etc/bandit_pass/bandit14, accessible only by user  bandit14. Instead of getting the next password, you receive a private SSH key for logging into the next level.

$ ssh bandit13@bandit.labs.overthewire.org -p 2220
bandit13@bandit:~$ ls -la
total 24
drwxr-xr-x  2 root     root     4096 Oct 16 14:00 .
drwxr-xr-x 41 root     root     4096 Oct 16 14:00 ..
-rw-r--r--  1 root     root      220 May 15  2017 .bash_logout
-rw-r--r--  1 root     root     3526 May 15  2017 .bashrc
-rw-r--r--  1 root     root      675 May 15  2017 .profile
-rw-r-----  1 bandit14 bandit13 1679 Oct 16 14:00 sshkey.private
bandit13@bandit:~$ exit
logout
Connection to bandit.labs.overthewire.org closed.

On your local machine

$ scp -P 2220 bandit13@bandit.labs.overthewire.org:sshkey.private .
$ chmod 400 sshkey.private 
$ ssh -i sshkey.private bandit14@bandit.labs.overthewire.org -p 2220
bandit14@bandit:~$ 

Explanation: You download the private key to access the next level using the scp command.


Bandit 14 Solution

To get the password for the next level, submit the current password to port 30000 on localhost.

$ ssh -i sshkey.private bandit14@bandit.labs.overthewire.org -p 2220
bandit14@bandit:~$ cat /etc/bandit_pass/bandit14 | nc localhost 30000
Correct!
BfMYroe26WYalil77FoDi9qh59eK5xNr

Explanation: After logging in as bandit14 using the private key, the nc command redirects the content of /etc/bandit_pass/bandit14.


Bandit 15 Solution

To retrieve the next password, send the current level's password to port 30001 on localhost using SSL encryption.

$ ssh bandit15@bandit.labs.overthewire.org -p 2220
bandit15@bandit:~$ cat /etc/bandit_pass/bandit15 | openssl s_client -connect localhost:30001 -quiet
depth=0 CN = bandit
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = bandit
verify return:1
Correct!
cluFn7wTiGryunymYOu4RcffSxQluehd

Explanation: The openssl s_client command establishes an SSL/TLS connection to transmit the content of /etc/bandit_pass/bandit15.


Bandit 16 Solution

Retrieve the next level's credentials by sending the current password to a port on localhost between 31000 and 32000. Identify which ports are active, and determine which support SSL and which do not. Only one port will provide the next credentials; others will echo your input.

$ ssh bandit16@bandit.labs.overthewire.org -p 2220
bandit16@bandit:~$ for i in {31000..32000} ; do
>   SERVER="localhost"
>   PORT=$i
>   (echo  > /dev/tcp/$SERVER/$PORT) >& /dev/null &&
>    echo "Port $PORT open"
> done
Port 31518 open
Port 31790 open
bash
Copy code
bandit16@bandit:~$ cat /etc/bandit_pass/bandit16 | openssl s_client -connect localhost:31790 -quiet
depth=0 CN = bandit
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = bandit
verify return:1
Correct!
-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAvmOkuifmMg6HL2YPIOjon6iWfbp7c3jx34YkYWqUH57SUdyJ
...
-----END RSA PRIVATE KEY-----
bandit16@bandit:~$ exit
logout
Connection to bandit.labs.overthewire.org closed.

Explanation: A simple port scanner in bash can be used to connect to open ports using openssl.


Bandit 17 Solution

Two files exist in the home directory: passwords.old and passwords.new. The next level's password is the only line that has changed in passwords.new from passwords.old.


$ ssh bandit17@bandit.labs.overthewire.org -p 2220
bandit17@bandit:~$ diff passwords.old passwords.new 
1c1
< 4s8TnZ7N6aiMbbG1P89rsgd2kboIh0y
---
> a8uD7jdsjdo7x1y7ep9urCn2ItCq34v
bandit17@bandit:~$ echo a8uD7jdsjdo7x1y7ep9urCn2ItCq34v

The password is a8uD7jdsjdo7x1y7ep9urCn2ItCq34v


Explanation: The diff command reveals the line that has changed between the two files.


Bandit 18 Solution

The password for the next level is located in the data.txt file. Within this file, you'll find a base64 encoded string.

bash
Copy code
$ ssh bandit18@bandit.labs.overthewire.org -p 2220
bandit18@bandit:~$ cat data.txt | base64 -d
The password is: f4d8d7a40d9b7a75dcab1780f2d451e1

The password is f4d8d7a40d9b7a75dcab1780f2d451e1


Explanation: The base64 -d command decodes the base64 string to reveal the next password.


Bandit 19 Solution

To proceed to the next level, you need to use the setuid binary located in the home directory. Run it without any arguments to see how it works. Once executed, you'll find the password for this level in the standard location: /etc/bandit_pass, after successfully using the setuid binary.

bash
Copy code
$ ssh bandit19@bandit.labs.overthewire.org -p 2220
bandit19@bandit:~$ ./bandit20-do
Run a command as another user.
  Example: ./bandit20-do id
bandit19@bandit:~$ ./bandit20-do cat /etc/bandit_pass/bandit20
GbKksEFF4yrVs6il55v6gwY5aVje5f0j

Explanation: This solution is straightforward and requires no additional clarification.


Bandit 20 Solution

In this level, there is a setuid binary in the home directory that connects to localhost on the port specified as a command-line argument. It reads a line of text from the connection and compares it to the password from the previous level (bandit20). If the password is correct, it transmits the password for the next level (bandit21).

To solve this:

  1. In the first terminal, set up a listener on a specified port (e.g., 31337) and output the password from the previous level.
  2. In the second terminal, run the setuid binary and connect to the same port.
  3. If the correct password is provided, the password for the next level will be displayed.

Explanation: Use two terminals—one to set the listener and the other to connect to it. The next password will appear in the first terminal.

ruby
Copy code
$ ssh bandit20@bandit.labs.overthewire.org -p 2220
# Terminal 1
bandit20@bandit:~$ nc -lp 31337 < /etc/bandit_pass/bandit20
gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr
# Terminal 2
bandit20@bandit:~$ ./suconnect 31337
Read: GbKksEFF4yrVs6il55v6gwY5aVje5f0j
Password matches, sending next password


Back to Blog