Post

OverTheWire: Bandit

OverTheWire: Bandit

Bandit

The Bandit wargame is aimed at absolute beginners. It will teach the basics needed to be able to play other wargames. It focuses on basic shell commands like

Tools: ls, cd, cat, file, du, find, grep, sort, uniq, base64, strings, nc.

SOLUTION

Level 0

Connect to shell host using ssh with username bandit0 and password bandit0 and host bandit.labs.overthewire.org.

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

After login, you will see the file readme, view content to get password: ???ZjLjTmM6FvvyRnrb2rfNWOZOTa6ip???

Level 1

Use password from bandit0 to login, you will see a file - can not view with normal command like cat or strings, use more instead. Password: 263JGJPfgU6LtdEvgfWU1XP5yac????

Level 2

You will see a file with special name --spaces in this filename--, use < or -- or ./ to view content. Password: MNk8KNH3Usiio41PRUEoDFPqfx????

1
2
3
cat < "--spaces in this filename--"
cat -- "--spaces in this filename--"
cat "./--spaces in this filename--"

Level 3

Your task is to read hidden file’s content. Use ls -la to display all files. Password: 2WmrDFRmJIq3IPxneAaMGhap0pF????

Level 4

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

List all file to see which file is human-readable.

1
2
3
4
5
6
7
8
9
10
11
12
file -- *

-file00: data
-file01: data
-file02: data
-file03: data
-file04: data
-file05: data
-file06: data
-file07: ASCII text
-file08: data
-file09: data

Level 5

Hint:

human-readable

1033 bytes in size

not executable

1
find . -size 1033c 2>/dev/null

-size 1033c: search for files that are exactly 1,033 bytes in size. The suffix c stands for characters (bytes).

2>/dev/null: This redirects standard error (stderr) to a special null device that discards all data.

Level 6

Hint

owned by user bandit7

owned by group bandit6

33 bytes in size

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

Level 7

1
grep millionth data.txt

Level 8

1
sort data.txt | uniq -u

sort data.txt: sorts all lines in the file alphabetically.

uniq -u: print unique

Level 9

1
strings data.txt | grep "=="

Level 10

1
2
echo “base64 string” | base64 -d

base64 -d: to decrypt base64 string

Level 11

where all lowercase (a-z) and uppercase (A-Z) letters have been rotated by 13 positions.

That means it’s ROT13, use cyberchef or dcode to decrypt it.

Level 12

Use List of file signatures to recognize the file type.

When we see the file’s content, we know that it is a hexdump. Compress it and decrypt it. But first, we need to copy data to tmp

1
mktemp -d

It will give you a random temporary directory, change directory to it and copy data.

1
2
xxd -r data.txt compressed
hexdump compressed

We will see 1f 8b, that means Gzip.

1
2
mv compressed data.gz
gunzip data.gz

Repeatedly decompress until you get the password!

64 61 74 61 for tar, to decompress, tar -xf

42 5A 68 for bz2, to decompress, bzip2 -d

Level 13

We have SSH key for bandit14, change mode for the key with chmod 600 key.

Login with ssh -i key

Level 14

The password for the next level can be retrieved by submitting the password of the current level to port 30000 on localhost. Get the current user’s password with

1
cat /etc/bandit_pass/bandit14

Connect localhost with netcat

1
2
nc localhost 30000
[password]

Level 15

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.

openssl s_client: implementation of a simple client that connects to a server using SSL/TLS.

1
2
openssl s_client -connect localhost:30001
[password]

Level 16

Find open ports on localhost with nmap

1
2
3
4
5
6
7
8
9
10
11
nmap -sV localhost -p 31000-32000
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-12-20 03:23 UTC
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00011s latency).
Not shown: 996 closed tcp ports (conn-refused)
PORT      STATE SERVICE     VERSION
31046/tcp open  echo
31518/tcp open  ssl/echo
31691/tcp open  echo
31790/tcp open  ssl/unknown
31960/tcp open  echo

We will see 2 port SSL, but only one of them is sus, 31790 unknown. But if we use the same technique in level 15, we will get KEYUPDATE. So we will add -ign_eof.

1
openssl s_client -ign_eof -connect localhost:31790

Level 17

See differences between 2 files with diff

Level 18

We can not use the password above for this level, look like someone has modified .bashrc to log us out when we log in with SSH.

1
ssh bandit18@bandit.labs.overthewire.org -p 2220 /bin/bash

/bin/bash spawn a bash shell

Level 19

1
2
3
4
5
6
7
8
9
ls -la
total 36

drwxr-xr-x   2 root     root      4096 Oct 14 09:26 .
drwxr-xr-x 150 root     root      4096 Oct 14 09:29 ..
-rwsr-x---   1 bandit20 bandit19 14884 Oct 14 09:26 bandit20-do
-rw-r--r--   1 root     root       220 Mar 31  2024 .bash_logout
-rw-r--r--   1 root     root      3851 Oct 14 09:19 .bashrc
-rw-r--r--   1 root     root       807 Mar 31  2024 .profile

We will see permission of bandit20-do is -rwsr-x---, which means it is a executable file. So let try to execute it.

1
2
3
./bandit20-do 
Run a command as another user.
  Example: ./bandit20-do whoami

So we will see how to use it now, .bandit20-do [command]

1
./bandit20-do cat /etc/bandit_pass/bandit20

Level 20

To send password, we will use the command below

1
echo -n 'password level 19' | nc -l -p 1234 &

echo -n prevents newline

-l listening

& to run in background

Now execute the file

1
./suconnect 1234

Level 21

Move to /etc/cron.d, we will see cronjob_bandit22, view its content, read source code of it.

Level 22

Same as Level 21

Level 23

Same as level 21, but we will see the code is little more complicated now. In short, the file will executed and deleted itself. So we will trick it by creating script to retrieve password and write it to another directory.

First, we create a temp directory using mktemp -d.

Move to there, create a file:

1
2
#!/bin/bash
cat /etc/bandit_pass/bandit24 > /tmp/tmp.?/pass

Create a file name pass using touch

Then give full permissions for them, and copy the script to /var/spool/bandit24/foo

1
2
3
4
5
chmod 777 pass
chmod 777 bandit24.sh
chmod 777 /tmp/tmp.?

cp bandit24.sh /var/spool/bandit24/foo

Wait a few minutes, read pass to get password.

Level 24

We will use brute-force attack for this level.

1
2
3
4
5
6
7
8
#!/bin/bash

for i in {0000..9999}
do
        echo gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8 $i >> pin.txt
done

cat pin.txt | nc localhost 30002 > result.txt

Create a list of pin numbers from 0000 to 9999, then send that list to localhost. Search for correct pin number with grep -i "correct" or grep -v "wrong".

Level 25

Minimize terminal and get the shell

Level 26

Level 27

Instead of login with ssh, we clone the repo with git

1
git clone ssh://bandit27-git@bandit.labs.overthewire.org:2220/home/bandit27-git/repo

password is from level 27.

Level 28

clone bandit28 repo, we will see its log, using git log, we have commit ID, use git show [ID] to get password

Level 29

Use git log --all --graph to list all commit ID, then git show

Level 30

Use git tag and git show

Level 31

Create a file with content May I come in?, then we will see the .gitignore, it won’t let you add any file with .txt. So we have to force it by using git add -f

Level 32

Every thing we type here will be UPPERCASED. The commands we have used so far however, are all lower-case and do not work. The one thing in Linux that is uppercase is variables. Specifically, the variable $0 has a reference to a shell.