Monday, July 6, 2015

OverTheWire - Bandit - Level 25

Level Goal

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 combinaties, called brute-forcing.

NOTE: This level requires you to create another shell-script so you aren't trying all combinations by hand

Commands you may need to solve this level

  • echo
  • nc
  • sort
  • seq
  • printf

Helpful Reading Material


Let's start by seeing how we can interact with the daemon.
nc localhost 30002
We'll get the following response: I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space.

We now know enough to be able to write our shell script that will brute-force this, however, it is important to note that this could take some time. Use CTRL+C to get out of the prompt.

Navigate to a tmp directory to be able to create your script which will look like the following:
#!/bin/bash

MAX_PIN=9999
RESULTS_FILE="/tmp/codebluedev/bandit25/results.txt"
BANDIT24_PASSWORD=$(cat /etc/bandit_pass/bandit24)
LAST_PIN_TRIED_FILE="/tmp/codebluedev/bandit25/last_pin_tried.txt"
LAST_PIN_TRIED=$(cat $LAST_PIN_TRIED_FILE)
SERVICE_HOST="localhost"
SERVICE_PORT=30002

for i in  `seq $LAST_PIN_TRIED $MAX_PIN`;
do
        echo $i > $LAST_PIN_TRIED_FILE
        echo "Pin $i..."
        printf "$BANDIT24_PASSWORD %04d\n " $i | nc $SERVICE_HOST $SERVICE_PORT >> $RESULTS_FILE
        RESULTS=`sort $RESULTS_FILE | uniq -u`
        if [ ${#RESULTS} -gt 2 ] && [$i != "1"];
        then
                echo "Pin is $i"
                echo $RESULTS
                exit
        fi
done
The top part of the script sets some variables that will be used throughout. The max pin variable is to tell the program how many attempts it should us. The results file is used to determine when we have found the correct pin because the response will be different from all of the failures. The password variable is grabbed from the bandit24 file (in case it changes) and is required to be the first input to the daemon we'll be trying to bruteforce. The last pin tried file stores the last pin sent to the daemon in case of a connection failure the script will not have to start up from the first pin code again. The last pin tried variable reads from this file to grab the last pin used. Service host and service port are just the values the daemon is listening on so we don't have to hardcode them into the script.

Now the script that actually does the work. We'll iterate over all values from last pin tried to the max pin variable using the seq command which is used to print a sequence of numbers. If you check the man page you'll see there are three options, we're using the second one and the increment defaults to 1. If we have no value in the last pin used file it also defaults to 1.

The first echo statement updates the last pin tried. The second echo statement just shows that progress is being made in the terminal so that we don't have to cat the last pin tried file to make sure the increment is working.

The next statement is what actually bruteforces the daemon. We pipe the password and the pin as a 4 digit number to the daemon in the format that it expects. We store the result of the command in the results file.

We then read the results file and sort it and pipe it to uniq so we don't have any extra failure values that would cause our logic to be incorrect.

We then check the results to see if the number of unique results contained in the file is greater than 2. If it is we have found the correct pin and print the results.

Run the script, wait several minutes (the answer as of this time is just under 6000 - you can use that to narrow down your attack vector size if you don't mind spoilers.

Use this password to log in to bandit25.

No comments:

Post a Comment