Blogs & Stories

SpiderLabs Blog

Attracting more than a half-million annual readers, this is the security community's go-to destination for technical breakdowns of the latest threats, critical vulnerability disclosures and cutting-edge research.

DEFCON 22 CTF Qualifiers Writeup

Hi folks!

I got to spend a little time playing the DEFCON 22 quals this previous weekend, presented by the Legitimate Business Syndicate (LegitBS), several of members of which are players in previous DEFCON CTF games. I didn't manage to make it very far, but such is life! I completed three of the four "Baby's First" challenges and would like to share my solutions with you.


This challenge was a service that played 3D tic-tac-toe with you. Whoever gets the most three-in-a-row runs won the round. Each round won increments your win counter, each round lost decrements it. When your win counter reaches -5, the service disconnects you. When your win counter reaches 50, the flag is displayed. Moves are specified using x,y,z coordinates of the slot to play. If you don't make a move in around three seconds, you are disconnected. If you make an illegal move (trying to play in a filled slot) the service simply repeats the prompt and waits for your next move.

Obviously the intention was for players to write a program that played 3D tic-tac-toe intelligently enough to gain a 50 round win advantage over the service. However, I wasn't about to write a 3D tic-tac-toe player (no offense, LegitBS).

To solve this challenge, I started out by examining how well the service played. It seemed as though the service played pretty poorly, so I figured that by making halfway intelligent moves I could win on a fairly regular basis. So instead of figuring out how to play intelligently, I wrote a list of the most advantageous positions on a 3D tic-tac-toe board.

In normal tic-tac-toe, the middle position is the most advantageous. This slot can be referred to as 1,1 (0,0 being top left and 2,2 being bottom right). This is because the middle slot can be used to complete four runs: two diagonal, one vertical, and one horizontal. In comparison, position 0,1 can only be used to complete two runs: one vertical and one horizontal. On a 3D tic-tac-toe board, the middle board is the most advantageous, and the middle slot of the middle board is highly valuable: It can be used to complete four runs on the middle board alone, as well as one depthwise run and EIGHT runs running diagonally through the three boards for a total of thirteen possible runs.

My solution was simply to write a python script that connected to the service and then played the most to least advantageous moves over and over again, detecting when each game was over and then starting from the top of the list again.

After about a half hour, my script was victorious and I had completed 3dttt.


This challenge claimed that it simply wanted to test your connection. All you have to do is download a torrent file, download the file from the torrent, and submit the md5 sum of the file. Easy, right? Of course not. THIS IS SPARTA LEGITBS.

The tracker wasn't responding, so it wasn't possible to simply torrent the file. Instead, you needed to tear apart the torrent file to get the needed information. I looked over the torrent file format spec to see what information I could glean about the files in the torrent. The metadata about each file includes:


file size in bytes

sha1 checksum of entire file

size of file chunks

sha1 checksum of each chunk concatenated together

The file was called "every_ip_address.txt" and it was about 57GB in size. The exact size of the file supported the assumption that the file contains every IP address from to, newline separated.

I first started out generating the file using nested loops in bash:

for a in {0..255};

do for b in {0..255};

do for c in {0..255};

do for d in {0..255};

echo $a.$b.$c.$d >> every_ip_address.txt;





Then I realized this was going to take a LONG time to complete. I had the overhead of file open and file close operations as well as the issues of speed inherent to bash scripting. So, I rewrote my script in Python to run a bit faster and to keep the file handle open so as to reduce overhead:

file = open('every_ip_address.txt', 'w')

for a in range(256):

for b in range(256):

for c in range(256):

for d in range(256):

file.write("%s.%s.%s.%s\n" % (a,b,c,d))


Suddenly it occurred to me: I'm working with a hash function. I don't need to use file operations at all, I can just feed data into an md5 engine line by line and then produce the digest when it's all finished. No need for the overhead of file operations and no need to waste 57 gigs of space holding IP addresses.

So, the final script was:

import md5

m = md5.new()

for a in range(256):

for b in range(256):

for c in range(256):

for d in range(256):

m.update("%s.%s.%s.%s\n" % (a,b,c,d))

print m.digest().encode('hex')

After submitting the md5 hash, I completed hackertool.


This was the only web-based challenge I saw in the CTF (except "nonameyet", which didn't end up being a web-based challenge for very long).

A "router" is exposed to the Internet with default credentials. There are a few common username and password combinations for routers in general, so I tried a few: admin/admin, admin/password, user/user, user/password, <nothing>/admin.

An empty username with password of admin allowed me access.

There were very few pages with any interactive content: The most interesting one was a diagnostic utility that allowed me to ping an arbitrary address. Javascript sanitization was applied, and all characters that weren't alphanumeric or periods were removed. However, given that the sanitization was client side, I was able to bypass it using an intercepting proxy. Since the output from the ping command was very similar to the output of the "ping" utility, I guessed that the web application was simply running a shell command with our input concatenated. I tried submitting the following:


The utility responded as though I'd put in "", so I figured I probably had shell command injection. I grabbed the perl reverse shell one-liner from the reverse shell cheat sheet and sent it in using the backtick method, which granted me a shell. The shell had sufficient permissions to read the flag file, so the challenge was complete.

Next year, I definitely need to bring more reverse engineering and memory corruption kung fu with me to the quals. That, and maybe a babysitter to keep my toddler from launching missiles while I focus on completing challenges.

See you all at DEFCON 22!