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.