Spoiler-Free OverTheWire Bandit Guide :: Levels 10 - 19


Welcome to part 2 of our OTW Bandit guide series! This part covers levels 10 to 19 and involves some very basic cryptography, common compression tools, and some basic networking tools.

Level 10

Goal: decode data.txt and get the password to the next level.

Hint: what is this random-looking string?

When you see multiple = at the end of a string containing mixed-case alphanumeric characters, it’s most likely a Base64-encoded string. Base64 uses = for padding.

Hint: any command line tool for decoding & encoding the string?

Yes! To decode & encode Base64, it’s (as you probably guessed) base64. Pass no option to encode from standard input, and -d to decode.

Level 11

Same as level 10, our goal is to decode data.txt and get the password to the next level.

Hint: another random-looking string? What’s this?

If you’re into CTFs and wargames, you will notice that cryptanalysis features often in this scene. With time and practice, it’ll be obvious what kind of cipher, encoding, or hash function you’re looking at each time.

And to build that intuition, I highly recommend using Identifying Unknown Ciphers from Practical Cryptography as a guide to identify any unknown cipher you encounter. And when you have some probable cipher in mind, dCode is the absolute best site for any deciphering need.

In this case, the official page for this level tells you that it’s a Caesar cipher and that it’s been rotated by 13 characters. Use dCode’s Caesar cipher page to decipher it.

Level 12

Goal: get the password from data.txt, which is a hexdump of a compressed file.

Whenever you see “hexdump”, xxd is your best friend. And be prepared, this level is a long one!

Hint: how do I read this hexdump?

Look at the man page of xxd. There’s an option to revert the dump file into the original binary.

Hint: how do I uncompress the binary?

You can find out how it was compressed with file. And then you look up the man page for the relevant compression tool to find the option to decompress it.

Level 13

Goal: log into the server as level14 with the private key called sshkey.private.

So far you’ve been logging into the Bandit server with passwords, but you can also log in via SSH with public key authentication if it’s enabled in the SSH server. You can either directly SSH into bandit14 or copy (either by just copying from the terminal display or using scp) it into your machine and SSH from there.

If you’re not familiar with public-key cryptography, here’s the wiki page about it. It’s absolutely one of the most important topics in cyber security. And if you’re interested in cryptography in general, I’d highly recommend Serious Cryptography by Jean-Philippe Aumasson. In my opinion, it’s very in-depth while being surprisingly engaging, not at all dry like most other cryptography textbooks.

Hint: permission too open?

If you copied the key onto your own machine, you might encounter this warning. SSH ignores key files if it has incorrect permissions, so you might need to execute chmod 700 <private key> (makes the key readable, writable, and executable only to the owner) to fix it.

Level 14

Goal: retrieve the password for the next level by sending the password for the current level to port 30000 on localhost.

The easiest way to send data to any port on any machine is via nc. And the password for the current level is located at /etc/bandit_pass/bandit14.

Hint: how do I use nc?

nc <IP> <port>

For example, to connect to localhost on port 80:

nc localhost 80

Level 15

This level is the same as level 14, but with SSL encryption!

If you’re wondering if nc can create connections with SSL, the answer is no. In this case, the s_client command of openssl will be the easiest way to connect over SSL.

What else does openssl do?

openssl is a huge toolkit of programs related to Public Key Infrastructure. It can generate certificates in all kinds of protocols (TLS, X.509, OSCP), RSA key pairs, and in this case, connect to SSL-enabled servers.

For example, to generate an 2048-bit RSA key pair:

openssl genrsa -out key.pem 2048 # to output the private key
openssl rsa -in key.pem -outform PEM -pubout -out public.pem # to output the public key

Hint: how do I use openssl s_client?

openssl s_client -connect <server>:<port>

Level 16

Goal: find an open port on localhost between 31000 and 32000 that will spit out the next password (in the form of a private key) when fed the current password. That port might also need to communicate over SSL.

When it comes to any automated port scanning needs, nmap is the most powerful tool for the job.

What is port scanning?

It’s when you find out whether a port is open and you repeat this process for a large range of ports. Most of the time you would automate this via scripting or with a tool like nmap.

What does it mean for a port to be open?

It means that a service (a basic example is a simple Python script) is listening on that port, ready to receive data.

What’s the practical application for port scanning?

Port scanning is usually part of penetration testing. In a black-box style penetration test, we port-scan the target and thus discover the listening services on them. Once we have that knowledge, we can then proceed to vulnerability anaylsis on each of the services.

You might need nmap too in some CTFs, or just to secure your own network and make sure no port is left open unintentionally.

Hint: how do I scan ports with nmap?

nmap -p <minimum port>-<maximum port> <server>

For example, to scan ports between 300 and 500 on google.com:

nmap -p 300-500 google.com

Level 17

Goal: find the password by figuring out the only line that differs from passwords.old in passwords.new.

Also like the official page for this level says, don’t panic when you log onto level 18, and it disconnects with the message “Byebye !”. That’s simply the next level’s challenge!

Hint: how do I use diff?

diff <file #1> <file #2>

It will list out the differing lines, with the order determined by the order of the files you specify.

Level 18

Goal: overcome the automatic logging out (set by ~/.bashrc) and get the password in the file readme in level18’s home directory.

Maybe instead of logging into the server and using our Bash shell interactively, there is a way to directly execute a command and get the output of it? Try reading the man page for ssh to find out!

What is .bashrc?

It’s a file to put your common Bash setup (your favourite custom functions, aliases, exports) and your interactive, non-login Bash shells will load this file so that you have access to your setup.

What’s the difference between interactive and non-interactive shells?

In short, interactive shells are ones with user interaction (e.g. the shell can prompt you for further input). Non-interactive ones are run by automated processes.

In the case of bash, you can start an interactive one with -i and a non-interactive one with -c.

Hint: how do I directly execute a command over SSH?

ssh <user>@<server> <your command>

Level 19

Goal: get the password via the setuid binary called bandit20-do in the home directory.

If you’re not too sure what bandit20-do does, try bandit20-do whoami. Remember that the password for bandit20 can be found at /etc/bandit_pass/bandit20.

What is setuid?

Setuid, short for set user id, is a flag on a binary that allows users to execute that binary on behalf of the binary owner.

For example, we want a program that allows users to change their own password on a system, which includes being able to modify the file /etc/shadow (on most Unix systems). But if users have the permission to modify it, they can technically change anyone’s password. So this won’t work.

What we need is a way to give the user temporary elevated privileges to alter /etc/shadow but otherwise protect it. So we write a program called passwd owned by root, set the setuid flag on it, and make sure that the program only changes the user’s own password entry. That’s how changing passwords on most Unix systems works.

What is euid?

When you start a process (by running id for example), the uid will always be your actual user ID. If you run a setuid binary, the uid is still your user ID but the euid (short for effective user ID) will be the owner of the binary instead.


We will be covering levels 20 to 29 in Part 3. There will be challenges involving cron jobs, git, and some scripting. Very exciting! I hope these hints have provided you with some extra context to these levels.

If you like my approach to CTF guides, maybe you’d like my fun & interactive cybersec courses too :)