Sunday, 11 December 2011

Beating the GCHQ challenge (part 3)

This final stage of the challenge is a windows-only affair. You get an executable file without much else.

*This challenge is a straight cracking/reverse-engineering exercise. I will not detail how I do this, but I will detail the puzzle that exists in the code.

Running the executable (in a safe, disposable virtual machine of course!) reveals that the executable needs an extra dll. A quick Google search reveals that this is the crypt module of cygwin, so I installed the correct libraries and tried again:

Entering the hostname of the challenge website at least told me that the program also wanted a licence file. From there I dived into the code and found the following:

  • A rather interesting string - "hqDTK7b8K2rvw".
  • Code that searches for a file named "licence.txt", sets aside 24 bytes of zeroed memory and then uses this memory to load the contents of the file.
  • The first 4 bytes of this data are checked against a hard coded value - 0x67636871. This is "gchq" in ascii. So far so good!
  • The next 20 bytes are then passed to the unix "crypt" function with the mystery string ("hqDTK7b8K2rvw") as a salt. The return is again checked against the mystery string and if its the same, the code continues.
  • At this point, the final 12 bytes of the licence are loaded onto the stack and the code branches to a new procedure.
  • This new procedure tries to contact the hostname you specified on port 80 and perform a HTTP  GET request. The URL used for this is interesting: "GET /%s/%x/%x/%x/key.txt HTTP/1.0\r\n\r\n". For the first string in this format specifier, the program passes the mystery string ("hqDTK7b8K2rvw"). The other 3 hex values are the 12 bytes read at the end of the licence.
Here's where it gets interesting. Looking at the crypt man-page, the function discards all but the first 8 bytes of the password and all but the first 2 bytes of the salt. The salt then becomes the first 2 bytes of the encrypted password (that is how the salt and encrypted password can be compared to see if the correct password is given). 

So I need to find a 20 byte password. How about "" a NULL char at the end? Nope. That didn't work :(

I realised that if I tried a brute force attack on this encrypted string it would take ages.  Also, as all but the first 8 chars are discarded, the final 12 bytes would not be revealed by the attack, and this was the information I needed. At this point I was stuck.

Then I remembered the weird information from the other 2 stages:

  • The jumped DWORD in stage 1 - 0xa3bfc2af
  • The firmware values from stage 2 - 0xd2ab1f05, 0xda13f110
Now, trying these values in the URL gives me

Go to that page and instead of a 404 page asking you to try again you get the following text: "Pr0t3ct!on#cyber_security@12*12.2011+". Put this into the form on and you get through to this:

You get a chance to apply for:
  • Cyber Security Specialist - GC10 (£25,446)
  • Senior Cyber Security Specialist - GC9 (£31,152)
And that's that for this year, unless there more in that final block of memory on stage 2!

No comments:

Post a Comment