Ganesh Prasad's blog

Playing the wargame Bandit on OverTheWire, Part - 1

October 13, 2025

What is the Bandit wargame ?

OverTheWire.org is an useful website for beginners on cybersecurity. It hosts a number of wargames to teach basic concepts in cybersecurity. A wargame is essentially an online game where the player hacks into provided hosts / servers to find hidden pieces of information to proceed to next levels. This provides some hands-on experience on how to exploit a server with certain vulnerabilities as well as how to protect against them.

Bandit is one such wargame hosted on OverTheWire. This is the simplest and most beginner friendly wargame on this host. It focuses on usage of basic unix commands and basics of various security featues on linux / unix. It consists of 33 levels. Player starts with Level 0, where the initial username-password is given to the player. Then on each level, some instrustions are given to the user to find the passord for the next level.

In this series of posts, I will go through each level and talk about how I approached and solved each of them. My solutions may or may not be similar to the canonical, most discussed solutions. My solutions may or may not be the best, most efficient either. My goal is to use my prior knowledge and expertise to find ways to solve the levels. I do not know each and every linux/command available, neither do I remember the flags, options supported by most of the commands (unless I actually use the commands frequently enough). But I do know some of the most common linux commands and their usage at an intermediate level, I also know programming fairly well (especially in C and Python). I will try to leverage my existing knowledge to find solutions. I may also use man to look up documentation of certain commands, may even search specific concepts on the internet (though I will try to limit the number of times I have to search the internet). The goal is to have fun with this wargame and to keep a note of the process as I go.

This is the Part 1 of this series of posts. We will cover levels 0 to 11 in this part. In the next part we will start from level 12. So, lets get started.

Prerequisites

Players must have a terminal application and a web browser to play this. For linux and mac users, it's fairly straightforward. For windows users, I would recommend using a linux based terminal by installing wsl (Windows subsystem for Linux) and then running a ubuntu or kali-linux based terminal from powershell using the wsl -d <distro-name>.

A working knowledge of basic unix commands, file system and python would also be required.

Level 0 --> Level 1

In Level 0, we are given the host, port, username and password to this level right away. The host (bandit.labs.overthewire.org) and port (2220) is same for all levels. For each level, the username is of the format bandit{level}, eg. for Level 1, the username will be bandit1. And we will have to login to each level using ssh and try to find the password for the next level.

For Level 0, we can login using ssh bandit.labs.overthewire.org -p 2220 -l bandit0. The -l flag is for the login_name, which is essentially the username. Then it'll ask for the password. For Level 0 the password is bandit0.

As per the instruction, the password for level 1 is in a file named readme. Let's run ls -al in the home directory and check if there is indeed a file called readme. There is one. Now let's see what's inside it by running cat readme. This does have the password for the next level in the last line. Let's copy it and logout (or exit).

Leval 1 --> Level 2

Let's login to Level 1 using ssh bandit.labs.overthewire.org -p 2220 -l bandit1 and then pasting the password copied from the last level. The instructions say that the password is in the file named -. Running ls confirms that there is a file named - in the home directory. But cat - won't work to display the contents (find why ?). So we need to find another way to look at its contents. A simple approach is to programmatically read the file and print the contents using python. Let's run python3 and use the following single liner to get the contents.

print(open('-', 'r').read())

It prints the password. Now let's copy it and exit (first from the python prompt and then from the ssh session).

Level 2 --> Level 3

Let's login to Level 2 using ssh bandit.labs.overthewire.org -p 2220 -l bandit2 and then pasting the password copied from the last level. In level 2 the password for the next level is stored in a file called --spaces in this filename-- located in the home directory.

So, we do not really need to think much, and just use the same method as the last level (use python) to get the password.

print(open('--spaces in this filename--', 'r').read())

Level 3 --> Level 4

Let's login to Level 3 using the password obtained from the last level as usual. The instructions say that the password is in a hidden file in a directory named inhere. In linux hidden filenames start with .. Let's just run ls -al inhere to see all the files inside the inhere directory. There is a file named ...Hiding-From-You in this directory. We can simply run cat to print the contents of this file.

cat inhere/...Hiding-From-You

Level 4 --> Level 5

Let's login to Level 4. The instruction says "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." It means, there should be at least one text file in the inhere directory, rest of the files must be binary.

Running ls inhere from the home directory confirms that there are 10 files with names like -file00, -file01 ... to -file09. Of course, we won't cat them (as they start with -). We will use python to check and print the contents. But at this point, we do not know which files text and which are binary. So we will try to open them as text files using python, this should fail for binary files work only for the text files. We can wrap this logic in a try block and ignore the errors to print only the text file.

import os

filenames = os.listdir('inhere')
for filename in filenames:
    try:
        print(open('inhere/' + filename, 'r').read())
    except:
        pass  

Level 5 --> Level 6

Let's login to Level 5. As per the instructions the password should be in a file inside inhere that meets the following criteria.

It means, the file must not be a binary, its size should be exactly 1033 bytes and it should not have the x flags set in its permissions. Let's first list all the files in the inhere directory using find and then for each file run ls -l <filename> to get the size and permission information. This can be done using

find inhere -type f

The -type f option tells find to output only files (not directories). Find does this recursively. This lists all the filenames inside the inhere directory and its subdirectories. But here we see that some files have spaces in their names. So we need to wrap the filenames with double quotes before passing them to ls -l.

find inhere -type f | xargs -L 1 -I % ls -l "%"

The -L 1 option tells xargs to consume the output of the previous command (find ... in this case) one line at a time. The -I % tells that xargs will use the placeholder % for the actual filename (input for the actual command run per line by xargs ; in this case ls -l).

This indeed prints the list of files with the size and permissions. We are interested in a file that has size 1033 bytes. Let's just pipe the list of file infos to grep and find the lines that have "1033" as a substring.

find inhere -type f | xargs -L 1 -I % ls -l "%" | grep 1033

This gives us just one file. And this file does not have the x flag set in its permissions (it's not executable). We do not need to search further, this is our file. We need to get its contents. Using cat we can print its contents and get the password.

Level 6 --> Level 7

Let's login to Level 6. The instruction says that the password for the next level is stored somewhere on the server and has all of the following properties:

This means the file with the password can be anywhere under the root directory (not just the home directory of the user bandit6). Let's try to find all files that are owned by user bandit7 and group bandit6 under /.

find / -type f -user bandit7 group bandit6

It prints a long list of files. All, except one, of which have the string permission denied. Just one file /var/lib/dpkg/info/bandit7.password does not print with error. This must be the one. Using cat we can see that it indeed has the password.

Level 7 --> Level 8

Let's login to level 7. The instruction says "The password for the next level is stored in the file data.txt next to the word millionth." There is an file named data.txt in the home directory. Running cat data.txt prints a long list of words and random strings. We need the random string next to the word 'millionth'. Let's pipe the contents of the file to grep and find the line with 'millionth'.

cat data.txt | grep millionth

There is just one line with the word 'millionth' and it has the password.

Level 8 --> Level 9

Let's login to level 8. The instruction says the password for the next level is stored in the file data.txt and is the only line of text that occurs only once. We can solve this easily using python. We just need to read the file data.txt, split it to lines, then get the count of occurances for each line (maybe using a Counter collection), check for a key with count 1.

from collections import Counter

lines = open('data.txt', 'r').read().split('\n')
lineCounts = Counter(lines)
for key in lineCounts:
  if lineCounts[key] == 1:
    print(key)

The printed line is the password.

Level 9 --> Level 10

Let's login to level 9. The instruction says that 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.

Again we can use python to process the data.txt file. Trying to open the file as a text file does not work. Despite the txt extension it seems to be a binary file. I got the contents of the file and printed it as byte string. There are only 3 places where mutiple = charcters can be seen (the human eye does pick up patterns quicky), only one of these seems to be the password (it's obvious).

print(open('data.txt', 'rb').read())

Level 10 --> Level 11

Let's login to Level 10. The instruction says the password is in the file data.txt in base64 encoded format. This can not be simpler. We just need to base64 decode the file.

base64 -d data.txt

This gives the password right away.

Level 11 --> level 12

Let's login to level 11. The instruction says that 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 a classic case of Caeser cipher (Cryptography 101) with the shift value already given (13).

We will again use python to read and decode this file. Let's write a quick function to decipher and use it.

def decodeCaeser(ciphertext, shift=13):
  plaintext = ''

  A = ord('A')
  a = ord('a')'

  charToTuple = lambda ch: (ord(ch)-A, A) if ch.isupper() else (ord(ch)-a, a)
  tupleToChar = lambda t: chr(t[0] + t[1])

  for ch in ciphertext:
    if not ch.isalpha():
      plaintext = plaintext + ch
      continue

    num, base = charToTuple(ch)
    rotated = ((num + shift + 26) % 26, base)
    plaintext = plaintext + tupleToChar(rotated)

  return plaintext

print(decode(open('data.txt', 'r').read()))

Wrapping up for today

Well, we solved 11 levels in one sitting. These were quite basic. I will stop for today here. In the next session (i.e. the next part of this series of blogposts) we will go through the subsequent levels. Today's wargaming session shows that we can use simple commands and beginner level knowledge of linux and python to solve these levels.