The Bandit wargames by OverTheWire is aimed at beginners and is lots of fun. It teaches the basics and many useful commands. Finding the solution is one thing, however eliminating other solutions and what you learn on the way is a great experience. Its highly recommend you try to solve these yourself before looking at the solutions. Note no keys or spoilers are found here.
OverTheWire can be found at http://overthewire.org/wargames/bandit/
1) Read the goals for each level and the suggested commands on overthewire.
2) Use the man <command> (manual) command to find out more on the suggested commands. eg: if you want to know more on ssh you can type man ssh. It will tell you what switches are available and how they work.
3) While in the man you can press “h” for help on using the manual. For example if you wanted to know more about using “version 2” you can press /version 2 and it will find occurrences of that text. Then n to move forward or N to move back.
4) If you can’t figure out the man. Google research the command and search for practical examples.
5) As a very last resort, search for other walk throughs. You shouldn’t give in, jumping straight to the solution means you don’t learn as much and you miss out on the satisfication of solving it your self : )
Level Walk Through’s
SSH in with given credentials
sh [email protected] -p 2220
ls shows one file. cat opens it up and gives level 1 key.
Appears to be only a file in /home/bandit1 called “-” and its ASCII text.
Checking file sizes shows there is something in there.
Trying to open this with cat appears to go nowhere, just appears to be waiting for something. Notice in the man for cat an exception for no file or when file is “-” read standard input.
While researching more the cat command, found a site that showed how to solve this one.
Enclosing the file name in quotes or using tab to autocomplete had the same affect. To the next level.
Using the ls command with a specific switch, reveals a hidden file. This was another easy one – check the man for more details.
We are told the key is on a human-readable file in the inhere directory. Using the du -ab command showed all files were the same size (33 bytes). But when checking the file type of all the files in there (note the wildcard *) showed “-file07” was ASCII text. Trying to open the data files just gave gibberish.
Logging in there are a lot of folders and files within. We are given the hint that the key is human-readable, 1033 bytes in size and not executable
Searching for human readable (assuming ASCII text) there are many but searching just on size we find only one file. (check man for find under -size)
The password for the next level is stored somewhere on the server and has all of the following properties: owned by user bandit7, owned by group bandit6 and 33 bytes in size. (check out the man for find under -size, -user, -group)
The solution I found while narrowing things down, still shows many “permission denied” errors in the results. I found a solution that tidies this up even further by amending 2>&1 | grep -v “Permission denied” to the end
Level up. The next password we are told is stored in the file data.txt next to the word millionth. A quick check shows the data.txt file we are after is right there in our home dir – however has many entries inside the file.
Hint – I used strings and grep commands to make this happen.
The next password we are told is stored in the file data.txt and is the only line of text that occurs only once. This time we have many passwords, just need to find one with the single occurrence.
Hint – I used 2 commands to make this happen. Also uniq does not detect repeated lines unless they are adjacent (from the –help)
The next password we are told is in the file data.txt in one of the few human-readable strings, beginning with several ‘=’ characters.
We could further refine the results below by using strings -n 20
These are fun. The next password we are told is stored in the file data.txt, which contains base64 encoded data.
The next password we are told is stored in the file data.txt, where all lowercase (a-z) and uppercase (A-Z) letters have been rotated by 13 positions.
The next password we are told is stored in the file data.txt, which is a hexdump of a file that has been repeatedly compressed.
A quick cat of the file shows data2.bin (possibly the file name before this was once converted to hex).
After some reading I found a way to reverse the operation of a hexdump we can use the xxd -r <filename> command.
Once converted back, as the problem says “repeatedly compressed” we need to know which compress algorithm/command was used. Using the file command we can find this out, then rename the file to suit what we need eg: mv data2.bin data2.gz then use the relevant command and switches to decompress eg: gzip -d data2.gz
Without spoiling the challenge, you repeat this process with all the compression commands until you are left with a ASCII text file with the key. Be sure to check the man for each command as some have different switches.
The next password we are told is stored in /etc/bandit_pass/bandit14 and can only be read by user bandit14. For this level, you don’t get the next password, but you get a private SSH key that can be used to log into the next level.
ssh <user>@<host> <private_key>
Using nmap we see the local SSH port is TCP22 (default). Out of interest using the file command we also see it is a RSA private key.
The man for ssh has an entry for using a identity for a private key. We use this with ssh to connect in as bandit 14. Note as localhost and not specifying the port number so it uses the default.
Once in we grab the key
We are told the password for the next level can be retrieved by submitting the password of the current level to port 30000 on localhost. This was an easy one. Check the man for netcat (aka nc) for specifying a port number.
nc -v <host> <port>
We are told the password for the next level can be retrieved by submitting the password of the current level to port 30001 on localhost using SSL encryption. Checking the man for a few of the suggested commands, it appears openssl s_client is what we will need. Also confirmed with nmap TCP port 30001 was open.
openssl s_client -connect <host>:<port> -ign_eof
This is going to be a good one. We are told the credentials for the next level can be retrieved by submitting the password of the current level to a port on localhost in the range 31000 to 32000. First find out which of these ports have a server listening on them. Then find out which of those speak SSL and which don’t. We start with nmap, scanning the range and its serVices – one port stands out.
nmap -<service/version> -<port range> <host>
openssl s_client -connect <host>:<port> -ign_eof
For this one, we appear to get a RSA private key?
We can save it to use later on. We can use mktemp to create a unique and temporary directory.
We then echo the key into the file.
When attempting to use the key to progress to the next level we get this error below.
To change permission on this file, and lock down we can use the below command. This will only allow the owner (us) access to the file. A good explanation can be found here on Linux permissions.
chmod 700 /tmp/tmp.aui92G7ZSw/bandit17
Now when we try again, we are in.
We are told the there are 2 files in the home directory: passwords.old and passwords.new. The password for the next level is in passwords.new and is the only line that has been changed between passwords.old and passwords.new. We want the line that is related to passwords.new – note the arrow indicating the line that matches the file on the right.
diff <file1> <file2>
We are told the password for the next level is stored in a file readme in the homedirectory. Unfortunately, someone has modified .bashrc to log you out when you log in with SSH. Sure enough when we ssh in, we get booted straight away.
Checking the man for ssh, we can run a command at the end.
ssh [email protected] -p 2220 “/bin/sh” don’t use bash for this session, try /bin/dash or /bin/sh
or ssh [email protected] -p 2220 “bash –noprofile –norc” which uses bash but with options to disable processing startup files
out of interest I open the .bashrc file to see what was causing it to exit.
We are told the we should use the setuid binary in the home directory. Execute it without arguments to find out how to use it. The password for this level can be found in the usual place (/etc/bandit_pass), after you have used the setuid binary. The only file in there is bandit20-do so we run that with no arguments. When checking the file its an ELF 32-bit Executable.
After figuring out how to use this, it appears when running the binary it runs as bandit20. We can test this by running the id command with and without the binary.
./bandit20-do cat /etc/bandit_pass/bandit20
We are told there is a setuid binary in the home directory that does the following: it makes a connection to localhost on the port you specify as a command line argument. It then reads a line of text from the connection and compares it to the password in the previous level (bandit20). If the password is correct, it will transmit the password for the next level (bandit21). This will be interesting as there was infrastructure changes.
We will need 2 terminals open on our local machine. Before connecting to otw we use a modified ssh command. On the first, we connect as normal but using the -L switch, this creates a local_socket:host:hostport.
ssh -l bandit20 -p 2220 -L 1234:localhost:22 bandit.labs.overthewire.org
Once in, we echo level 19’s password and pipe into ncat using the -l switch to “bind and listen for incoming connections” and the -v for verbose – to see more output. The final parameter is the port number – 6969 because its funny. This is now running waiting for a connection.
echo <level19pwd> | ncat -lv 6969
Now on our local machine we open up 2nd shell and ssh to localhost and port number (1234) we setup before. Though some wizardry we end up in the same session on the remote end.
ssh [email protected] -p 1234
Now in the 2nd shell we use the binary and connect to port 6969. This then sends the next password back to terminal 1. This took a long time to get working, but I learnt a lot in the process.
We are told a program is running automatically at regular intervals from cron, the time-based job scheduler. Look in /etc/cron.d/ for the configuration and see what command is being executed. Checking out the /etc/cron.d/ we find a job under bandit22.
Then checking out /usr/bin/cronjob_bandit22.sh we find a script which is doing two things:
1) modifying permissions on a temporary file (owner: r-x, group: r–, users: r–)
2) then reading a file and writing it to the temp file
Sure enough, when we read the temp file we find the next key!
Again we are told a program is running automatically at regular intervals from cron. Following the same path as the previous level we find a script.
Running the default script cronjob_bandit23.sh copies the level22 password (which we already know) to a temp file.
To get the temp file location for bandit23 use echo I am user bandit23 | md5sum | cut -d ‘ ‘ -f 1 then read the temp file.
Again we are told a program is running automatically at regular intervals from cron and we will have to create a bash script to solve the level.
Looks like the job is running every minute as user bandit24 (More details on cron here). Scripts are run from /var/spool/$myname, then deleted.
At /var/spool the only usable folder there is bandit24. We can’t create any folders here or list what is in the bandit24 directory. But looks like we can copy files in there – a script perhaps?
I create a temp directory with mktemp -d and a temp file (touch) use an editor to create my script in there (3 lines). Modify its permissions (chmod) so anyone can read and execute it. Use the file command to confirm it is indeed a shell script and will be executed. Then copy it to the /var/spool/bandit24/ folder and await execution. I use the date command to impatiently check the time.
Through shell wizardry, the key for the next level appears in the temp file I created.
We are told a daemon is listening on port 30002 and will give you the password for bandit25 if given the password for bandit24 and a secret numeric 4-digit pincode. There is no way to retrieve the pincode except by going through all of the 10000 combinations, called brute-forcing.
First we create a temp working directory mktemp -d to play in. Next we try connecting to it to see what happens. We find it requires a specific syntax.
Without spoiling the fun, I approached this many ways before finding a quick solution and spent a long time on this level. But on the upside learnt how to use vim and python. The most satisfying level so far.
Create the python file vim bandit24.py and create the content, make it executable chmod +x bandit24.py then run it.
We are told logging in to bandit26 from bandit25 should be fairly easy… The shell for user bandit26 is not /bin/bash, but something else. Find out what it is, how it works and how to break out of it. Similar to level 16 we find a private key. But when used to connect, we get booted off straight away.
Looks like bandit26 is using a shell at /usr/bin/showtext. Assume text.txt is the BANDIT26 logo displayed above (we can’t read this). There is an exit 0 command at the end which is booting us out.
I spent a fair chunk of time on this before searching for a hint. This is a very simple yet clever problem. The hints I would give is focus on the showtext file and look more closely.
Tried usermod –shell /bin/bash bandit26. No access to change /etc/passwd. No access to modify the /usr/bin/showtext file. Tried ssh -i <key> <user>@<host> “bash –noprofile –norc”. Tried SSH with different shells listed at /etc/shells eg: ssh -i <key><user>@<host> /bin/sh then ls to see if anything comes up. Tried commands to copy the key back to my home dir ssh -i <key> <user>@<host> “cat /etc/bandit_pass/bandit26 >> tmp/<file>”. Tried all the files involved in an interactive login.