Capture the Swag

Friday, December 11, 2015

Short break but we're back CTFing. I've been away because I took a month of lab time doing the OSCP certification which I will write a review of later. It was very fun though. Today I'm writing up how I solved this challenge at SecCon 2015 since it was one I spent some non-trivial time on.

A nonogram is a type of Japanese crossword type puzzle with numbers. You fill in boxes based on numbers in the rows and columns and eventually make a picture.

The SecCon implementation looked like this (NO! added for comedic effect :P ):

I looked into solving the puzzle category itself but grew tired of reading the rules and instead looked at solving engines other people had written.

I first selected this one from Github. The solver worked and was simple to integrate with some simple network code but it was very slow and often tried to perform useless exhaustive searches for perfect solutions which just didn't ever seem to end.

That was where I spent most of my time on this challenge, diagnosing why Nonograms take time to solve. I found that there's often more than one solution and sometimes there are many possible solutions.

Sounded good and, again was in Python, so I basically swapped out the old engine of my solution for this one in a couple of minutes and immediately saw results. The solver was way faster and knew how to give up after finding 2 (or, modified as many as you like) possible solutions.

With that engine, some very rough web and table parsing code, and we had a solver for this challenge that would:

Grab the first / next challenge nonogram table

Parse for the values in the first column and top row into two zero padded lists

Feed that into the Google constraint programming engine via some borrowed Python code

Get a text output, write that using Python Image Library to a PNG file

Parse the PNG for a QR code

Send the QR code decoded output to the server and fetch the next challenge

We had to do this a total of 30 times and the solutions aren't always perfect and the QR codes don't always work so a few attempts need to be run.

Anyway, I include the code before, sorry you have to see this messy hack but I don't mind, 300 points it got me :)

Anyway, it was actually fun to solve this as I always do like the challenge response type problems. I probably suffered a bit here from trying to reuse some of the code I previously used for another challenge but not too badly.

Ok so online sandboxes we can run code in. Great, but I'm on a deadline here... Oh whats this:

I don't know, Am I?

I click that link (http://code.runnable.com/) and I'm taken to the meat of their site, a list of code snippets we can run for various reasons. I pick one at random and am greeted with a surprise. Each code snippet gets a kind of web-based terminal to interact with:

Thursday, October 22, 2015

A mid week CTF when I have final exams! Argh! Still I play because I'm an idiot. Fun CTF, hard to read the font they chose but still fun. This was a classical RSA challenge with almost no difficult points but I'll write up anyway.

Ok so the linked file is a PCAPNG file and we're given two RSA public keys.

Immediately I'm thinking those modulii are too small and so I just go and plug them into factordb.com. I'm rewarded and have our p & q values for both Alice and Bob:

Monday, October 19, 2015

I didn't get time to play Hackover 15 as much as I wanted. It looked like a really fun competition but unfortunately it overlapped with Hitcon 2015. However I woke up super early (6am Saturday - eek!) to get a few hours in on Hackover before Hitcon started.

Here's an RE challenge I did very quickly and I just want to show how sometimes the environment you work in gives you a leg up. In this case PEDA (the GDB add-on) gave me the flag faster than I could reverse the binary.

The clue was:

The file, a compressed tarball, contains just one file: "goto.bin" which identifies as "data" with file...

We now have the meat of the challenge, the ELF binary. Executing it, as we saw, simply asks for a PASSWORD:. I assume the flag is the password. Either way off to IDA Pro we go....

I decide to dynamically examine comparison points before diving in to perform a full static analysis. Often times simpler RE challenges can be solved rapidly with dynamic analysis, skipping a lot of time on the static analysis. I decide to set breakpoints at obvious loops.

The second such loop I examine is this one, I set a breakpoint at 0x4006aa (the cmp instruction):

Ok nothing so far, let's watch this loop for a while. I hit "c" for continue and watch the screen idly while the loop iterates. It's about at this point I stop because I notice a string being built in memory...

I don't mind admitting that Hitcon was HARD. Possibly some of the hardest challenges I've faced CTFing so far. Or maybe I was just rusty. Anyway here's one challenge I found particularly rewarding from Hitcon 2015.

The clue was fairly cryptic, not giving anything away. It simply delivered a compressed tarball...

When extracting the tarball we are rewarded with two files: "encrypt" and "flag.puzzle":

Above you can see the important bits of the code, it takes the command line argument, hashes it with SHA1 and uses the SHA1 output as a key across the input file. It spreads the key bytes across 20 even blocks of the input, using XOR of one of the key bytes per block.

So in theory, all we need to do to solve this is:

Divide the input into 20 evenly sized blocks

Discover the single-byte XOR key for each block, decrypt the block

Re-assemble the file into the decrypted output

Easy?!

To begin with, we use an old trick of a known plaintext attack. We think up likely strings that might appear somewhere in the file in order to get a headstart on some of the blocks.

I try obvious ones first, JFIF, GIF and PNG as input strings, and using the "xorsearch" tool I quickly discover the encrypted file is probably a PNG:

So we found two pieces of information here, the file format (PNG) and the XOR key for the first block (0x65).

Next I split the file into blocks, before I do though, I use a quick Python script to double-check the actual block size being used here:

#!/usr/bin/pythonimportsubprocessopen('generated.plaintext','w').write('A'*1135)ctext=subprocess.check_output(['./encrypt','a','generated.plaintext'])firstbyte=ctext[0]forbinrange(0,len(ctext)):ifctext[b]!=firstbyte:print"blocksize is "+str(b)quit()

Which returns:

root@mankrik:~/hitcon/puzzleng/writeup# ./c.py
blocksize is 57

So we can use split to extract the chunks:

root@mankrik:~/hitcon/puzzleng/writeup# split -b 57 -d flag.puzzle

Next we can use the known plaintext attack against further chunks. We know PNG files contain IDAT before image data chunks and end with "IEND", we use that to recover two more keys:

Great, getting somewhere. We have 3/20 keys. What other patterns can we use for this attack?

Well PNGs can contain several IDAT chunks, but nope we don't find any evidence of that in this image. No Exif data. Hmm. 17 files each with 256 possible keys adds up to a lot of possible image files.

I was stuck here a while, until i decided to look for non obvious patterns. Luckily I found two such patterns very quickly. Inside the final chunk, decrypted using the key we found with xorsearch above, we see the following: