Challenge Information

Platform: OverTheWire
WarGame: Bandit
Levels: 17-24

Level 17

Objective: 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.

Note: If you have solved this level and see Byebye! when trying to log into bandit18, this is related to the next level, bandit19.

Solution: First, we change the permissions for the SSH private key on our local machine.

# on local machine
chmod 0400 <private-ssh-key-file>
Listing 1 - Modifying file permissions

Next, we use the key to connect to level 17.

# on local machine
ssh -i <private-ssh-key-file> [email protected] -p 2220
Listing 2 - Specifying a private key for the SSH connection

Once connected, we compare the two files with the diff command to identify the changed line.

diff passwords.old passwords.new
Listing 3 - Comparing different versions of the same file

Level 18

Objective: The password for the next level is stored in a file readme in the home directory. Unfortunately, someone has modified .bashrc to log you out when you log in with SSH.

Solution: We specify cat as a command to be executed immediately after SSH login, thereby bypassing the forced logout triggered by .bashrc.

ssh [email protected] -p 2220 cat ./readme
Listing 4 - Bypassing automatic logout

Level 19

Objective: To gain access to the next level, you 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.

SUID: “Setuid (set user ID) is a Unix-like system permission that allows a file to be executed with the permissions of the file’s owner, not the user running it.”

Solution: We run the executable with the set user ID (SUID) bit to read the password file as bandit20 rather than bandit19.

./bandit20-do cat /etc/bandit_pass/bandit20
Listing 5 - Reading the password file with the setuid binary

Level 20

Objective: 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 commandline 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).

Note: Try connecting to your own network daemon to see if it works as you think.

Solution: First, we run a Netcat listener in the background on an arbitrary port and pipe the current level’s password to it. Then we execute the SetUID binary, which connects to our listener, receives the password, and returns the next level’s password.

echo "<bandit20-password>" | nc -l localhost 62333 &
./suconnect 62333
Listing 6 - Connecting with the setuid binary

Level 21

Objective: 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.

Solution: We examine the running cron jobs and observe that cronjob_bandit22 executes a script every minute. Inspecting the script reveals the location of the password.

# examine the cron job
cat /etc/cron.d/cronjob_bandit22

# examine the script executed every minute
cat /usr/bin/cronjob_bandit22.sh

# retrieve the password; the file location is indicated in the script
# (the following is an example of a temporary file that was generated)
cat /tmp/t7O6lds9S0RqQh9aMcz6ShpAoZKF7fgv
Listing 7 - Examining the cron job, the executed script, and the password file

Level 22

Objective: 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.

Note: Looking at shell scripts written by other people is a very useful skill. The script for this level is intentionally made easy to read. If you are having problems understanding what it does, try executing it to see the debug information it prints.

Solution: As before, we examine the cron job and the script it executes. To determine the correct filename, we replicate the commands used in the script to generate the hash, substituting bandit23 for the $whoami variable.

# examine the cron job
cat /etc/cron.d/cronjob_bandit23

# examine the script executed every minute
cat /usr/bin/cronjob_bandit23.sh

# replicate the commands to generate the filename
echo I am user bandit23 | md5sum | cut -d ' ' -f 1

# retrieve the password from the generated file
cat /tmp/8ca319486bfbbc3663ea0fbe81326349
Listing 8 - Cron job, executed script, and obfuscated password filename

Level 23

Objective: 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.

Note-1: This level requires you to create your own first shell-script. This is a very big step and you should be proud of yourself when you beat this level!

Note-2: Keep in mind that your shell script is removed once executed, so you may want to keep a copy around…

Solution:

# examine the cron job
cat /etc/cron.d/cronjob_bandit24

# examine the script executed every minute
cat /usr/bin/cronjob_bandit24.sh
Listing 9 - Examining the cron job and the executed script

The contents of the executed script are as follows:

#!/bin/bash

myname=$(whoami)

cd /var/spool/$myname/foo || exit 1
echo "Executing and deleting all scripts in /var/spool/$myname/foo:"
for i in * .*;
do
    if [ "$i" != "." -a "$i" != ".." ];
    then
        echo "Handling $i"
        owner="$(stat --format "%U" ./$i)"
        if [ "${owner}" = "bandit23" ]; then
            timeout -s 9 60 ./$i
        fi
        rm -rf ./$i
    fi
done
Listing 10 - Contents of cronjob_bandit24.sh

As we can see, the script executes and then immediately deletes all scripts (including hidden ones) located in the /var/spool/bandit23/foo/ directory. Therefore, we must create a script that reads the password for bandit24.

First, we create a temporary file where we have ownership permissions. This is where we will store the retrieved password.

# create a temporary file with owner permissions
mktemp

# the output provides the path to our temporary file
# for example: /tmp/tmp.SfdgYS0COS
Listing 11 - Creating a temporary file

Next, we navigate to the /var/spool/bandit23/foo/ directory and create our script. A simple example follows:

#!/bin/bash
cat /etc/bandit_pass/bandit24 >> /tmp/tmp.SfdgYS0COS
Listing 12 - Script to copy the password

After saving the file – for example, as grabtheflag.sh – we make it executable.

# grant execute permissions to all users
chmod a+x grabtheflag.sh
Listing 13 - Adding executable permissions to the script

We then wait briefly (less than sixty seconds) and check our temporary file for the password.

Note: We must save the script and make it executable quickly, as any script in the directory is deleted every sixty seconds.

Level 24

Objective: 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. You do not need to create new connections each time

Solution: First, we create a temporary directory in which we have ownership rights.

# create a temporary directory
mktemp -d

# navigate to the directory
cd <your-temp-dir>
Listing 14 - Creating a temporary directory

We then create a script that generates all possible combinations of the password and four-digit PIN codes.

#!/bin/bash

# password for level 24
password="<bandit24-password>"

# generate all four-digit combinations from 0000 to 9999
for i in {0000..9999}
do
    echo "$password $i" >> passwords.txt
done
Listing 15 - Generating password and PIN combinations

After making the script executable, we run it to generate the combinations.

# make the script executable
chmod a+x <your-script-name>

# execute the script
./<your-script-name>
Listing 16 - Executing the generation script

We then use netcat to open a TCP connection to port 30002 and feed the combinations to the daemon. We redirect the output to a file so we can search for the correct response.

cat passwords.txt | nc -vN localhost 30002 > output.txt
Listing 17 - Submitting combinations to the daemon

Finally, we clean up our temporary files.

# return to the home directory
cd /home/bandit24

# remove the temporary directory and its contents
rm -rv <your-temp-dir>
Listing 18 - Cleaning up temporary files