This is howto win canyoucrackit.co.uk, please see the
Source.
[+]Contents
----------------
1. Background |
2. Requirements|
3. Stage One |
4. Stage Two |
5. Stage Three |
6. The End...? |
----------------
[+] Background
---------------
Earlier this week a mysterious website appeared at the url canyoucrackit.co.uk.
I saw the url being passed around Twitter and eventually my curiousity got the best of me.
At first, not much was known about the purpose or origin on the website and the code challenge
displayed. The goal is obviously to break the code that appears in the image and enter the password afterwards.
Well, it turns out that the website is
hosted by GCHQ. The United Kingdom's spy agency. The website is their
advertisement for a job application, more or less. After you complete
the challenge, enter the code and click 'Okay' you are redirected to a
website where you can apply for a job at the MI5 as a 'Cyber Security
Specialist.' Unfortunately, the job only offers 25k yearly to start. And
you need to be a UK citizen. Starting to look like alot of work for not
much reward, right? Again, my curiousity won and I tried my luck at
cracking the code...not for the job but just for the satisfaction of
actually completing it.
I did cheat alittle bit for the second stage of the challenege. You'll see why...
[+] Requirements
-----------------
* NASM
* Cygwin w/ needed DLLs
* GDB
* Hex Editor
* Coding Knowledge (C/C++ or Python)
* Objdump
* Patience, Cigarettes & Coffee
[+] Stage One
-------------------
Visit canyoucrackit.co.uk and save the image file that contains the code (cyber.png)
You can either manually copy the code in the image or feed the image into an OCR.
After you have the code saved to a text file, open up cyber.png in your Hex Editor. I used GHex.
When you open cyber.png in the hex
editing application, in the beginning you should notice a string that
starts with 'iTXtComment' followed by a string of numbers and letters
which end with '==' That is a base64 code.
Save the base64 string, decode it and add it to the beginning of your code from the image.
Base64 Code:
QkJCQjIAAACR2PFtcCA6q2eaC8SR+8dmD/zNzLQC+td3tFQ4qx8O447TDeuZw5P+0SsbEcYR78jKLw==
Image Code:
eb 04 af c2 bf a3 81 ec 00 01 00 00 31 c9 88 0c
0c fe c1 75 f9 31 c0 ba ef be ad de 02 04 0c 00
d0 c1 ca 08 8a 1c 0c 8a 3c 04 88 1c 04 88 3c 0c
fe c1 75 e8 e9 5c 00 00 00 89 e3 81 c3 04 00 00
00 5c 58 3d 41 41 41 41 75 43 48 3d 42 42 42 42
75 3b 5a 89 d1 89 e6 89 df 29 cf f3 a4 89 de 89
d1 89 df 29 cf 31 c0 31 db 31 d2 fe c0 02 1c 06
8a 14 06 8a 34 1e 88 34 06 88 14 1e 00 f2 30 f6
8a 1c 16 8a 17 30 da 88 17 47 49 75 de 31 db 89
d8 fe c0 cd 80 90 90 e8 9d ff ff ff 41 41 41 41
Save your file that combines these two codes as a binary file.
Run this through objdump with: objdump -d -D -b binary -mi386 crackme.bin
Open with your debugger (gdb) and set a
breakpoint at the INT 0x80 call. When it hits your breakpoint, use the
gdb command 'bt' (which dumps the current stack.) A decrypted string
will be visible in the stack dump.
GET /15b436de1f9107f3778aad525e5d0b20.js HTTP/1.1
Throw that in your browser behind canyoucrackit.co.uk and you're on your way to Stage Two!
You feel elite all ready, right? Yeah, I thought so..
*Stage One Solution: http://canyoucrackit.co.uk/15b436de1f9107f3778aad525e5d0b20.js
[+] Stage Two
------------------
Download the .js file from the url you
visited as the Stage One solution. The js file contains VM information
that you need to emulate and then dump the memory while emulating to
find the next clue. When you run the VM emulation code you write, once
the VM reaches the HLT instruction the memory will contain a large chunk
of data. This data contains two decryption codes and the solution text
which is decrypted by the 2nd decryption code in the data chunk.
To be honest, this is where I cheated
alittle bit. Writing a python or C code to emulate a VM didn't exactly
sound like a good use of time to me. It's not especially hard but the
code is just long and involved. So I googled around a bit and found a
Pastebin.com link to a Python script someone all ready had written for
this exact challenge. There wasn't an authors name attached to the file
but whoever you are, I thank you kindly.
The code is listed directly below. It
will run the VM and needed decryption and finally dump the memory that
includes the decrypted string. Copy this code, save it as stage2.py and
run.
--------------------------------Stage Two Solution Code---------------------------------------
#!/usr/bin/python
mem=[0x31, 0x04, 0x33, 0xaa, 0x40,
0x02, 0x80, 0x03, 0x52, 0x00, 0x72, 0x01, 0x73, 0x01, 0xb2, 0x50,0x30,
0x14, 0xc0, 0x01, 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x98,
0xab, 0xd9, 0xa1, 0x9f, 0xa7, 0x83, 0x83, 0xf2, 0xb1, 0x34, 0xb6, 0xe4,
0xb7, 0xca, 0xb8,0xc9, 0xb8, 0x0e, 0xbd, 0x7d, 0x0f, 0xc0, 0xf1, 0xd9,
0x03, 0xc5, 0x3a, 0xc6, 0xc7, 0xc8, 0xc9,0xca, 0xcb, 0xcc, 0xcd, 0xce,
0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,0xda,
0xdb, 0xa9, 0xcd, 0xdf, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
0xe7, 0xe8, 0xe9,0x26, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2,
0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,0x7d, 0x1f, 0x15, 0x60, 0x4d,
0x4d, 0x52, 0x7d, 0x0e, 0x27, 0x6d, 0x10, 0x6d, 0x5a, 0x06, 0x56,0x47,
0x14, 0x42, 0x0e, 0xb6, 0xb2, 0xb2, 0xe6, 0xeb, 0xb4, 0x83, 0x8e, 0xd7,
0xe5, 0xd4, 0xd9,0xc3, 0xf0, 0x80, 0x95, 0xf1, 0x82, 0x82, 0x9a, 0xbd,
0x95, 0xa4, 0x8d, 0x9a, 0x2b, 0x30, 0x69,0x4a, 0x69, 0x65, 0x55, 0x1c,
0x7b, 0x69, 0x1c, 0x6e, 0x04, 0x74, 0x35, 0x21, 0x26, 0x2f, 0x60,0x03,
0x4e, 0x37, 0x1e, 0x33, 0x54, 0x39, 0xe6, 0xba, 0xb4, 0xa2, 0xad, 0xa4,
0xc5, 0x95, 0xc8,0xc1, 0xe4, 0x8a, 0xec, 0xe7, 0x92, 0x8b, 0xe8, 0x81,
0xf0, 0xad, 0x98, 0xa4, 0xd0, 0xc0, 0x8d,0xac, 0x22, 0x52, 0x65, 0x7e,
0x27, 0x2b, 0x5a, 0x12, 0x61, 0x0a, 0x01, 0x7a, 0x6b, 0x1d, 0x67,0x75,
0x70, 0x6c, 0x1b, 0x11, 0x25, 0x25, 0x70, 0x7f, 0x7e, 0x67, 0x63, 0x30,
0x3c, 0x6d, 0x6a,0x01, 0x51, 0x59, 0x5f, 0x56, 0x13, 0x10, 0x43, 0x19,
0x18, 0xe5, 0xe0, 0xbe, 0xbf, 0xbd, 0xe9,0xf0, 0xf1, 0xf9, 0xfa, 0xab,
0x8f, 0xc1, 0xdf, 0xcf, 0x8d, 0xf8, 0xe7, 0xe2, 0xe9, 0x93, 0x8e,0xec,
0xf5, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,0x37, 0x7a, 0x07, 0x11, 0x1f, 0x1d, 0x68, 0x25, 0x32,
0x77, 0x1e, 0x62, 0x23, 0x5b, 0x47, 0x55,0x53, 0x30, 0x11, 0x42, 0xf6,
0xf1, 0xb1, 0xe6, 0xc3, 0xcc, 0xf8, 0xc5, 0xe4, 0xcc, 0xc0, 0xd3,0x85,
0xfd, 0x9a, 0xe3, 0xe6, 0x81, 0xb5, 0xbb, 0xd7, 0xcd, 0x87, 0xa3, 0xd3,
0x6b, 0x36, 0x6f,0x6f, 0x66, 0x55, 0x30, 0x16, 0x45, 0x5e, 0x09, 0x74,
0x5c, 0x3f, 0x29, 0x2b, 0x66, 0x3d, 0x0d,0x02, 0x30, 0x28, 0x35, 0x15,
0x09, 0x15, 0xdd, 0xec, 0xb8, 0xe2, 0xfb, 0xd8, 0xcb, 0xd8, 0xd1,0x8b,
0xd5, 0x82, 0xd9, 0x9a, 0xf1, 0x92, 0xab, 0xe8, 0xa6, 0xd6, 0xd0, 0x8c,
0xaa, 0xd2, 0x94,0xcf, 0x45, 0x46, 0x67, 0x20, 0x7d, 0x44, 0x14, 0x6b,
0x45, 0x6d, 0x54, 0x03, 0x17, 0x60, 0x62,0x55, 0x5a, 0x4a, 0x66, 0x61,
0x11, 0x57, 0x68, 0x75, 0x05, 0x62, 0x36, 0x7d, 0x02, 0x10, 0x4b,0x08,
0x22, 0x42, 0x32, 0xba, 0xe2, 0xb9, 0xe2, 0xd6, 0xb9, 0xff, 0xc3, 0xe9,
0x8a, 0x8f, 0xc1,0x8f, 0xe1, 0xb8, 0xa4, 0x96, 0xf1, 0x8f, 0x81, 0xb1,
0x8d, 0x89, 0xcc, 0xd4, 0x78, 0x76, 0x61,0x72, 0x3e, 0x37, 0x23, 0x56,
0x73, 0x71, 0x79, 0x63, 0x7c, 0x08, 0x11, 0x20, 0x69, 0x7a, 0x14,0x68,
0x05, 0x21, 0x1e, 0x32, 0x27, 0x59, 0xb7, 0xcf, 0xab, 0xdd, 0xd5, 0xcc,
0x97, 0x93, 0xf2,0xe7, 0xc0, 0xeb, 0xff, 0xe9, 0xa3, 0xbf, 0xa1, 0xab,
0x8b, 0xbb, 0x9e, 0x9e, 0x8c, 0xa0, 0xc1,0x9b, 0x5a, 0x2f, 0x2f, 0x4e,
0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
vm_instructions= ["jmp", "movr", "movm", "add", "xor", "cmp", "jmpe", "hlt"]
vm_segment_size=0x10
cs=4
ds=5
def ModDetect(opcode):
if (opcode&0x10)==0:
return False
return True
def GetOpcode(opcode):
return (opcode>>5)
def GetOperand1(opcode):
return (opcode&0x0F)
########################################################################
class _VM_CPU:
vm_ip=0
vm_reg=[0 for i in range(6)]
vm_flag=0
class VirtualMachine:
vm_cpu=_VM_CPU()
mem=[]
def __init__(self,mem):
self.mem=mem
self.vm_cpu.vm_reg[ds]=0x10
print "ip:%3X" %(self.vm_cpu.vm_ip),
print "fl:%2X" % (self.vm_cpu.vm_flag),
print "r0:%2X" % (self.vm_cpu.vm_reg[0]),
print "r1:%2X" % (self.vm_cpu.vm_reg[1]),
print "r2:%2X" % (self.vm_cpu.vm_reg[2]),
print "r3:%2X" % (self.vm_cpu.vm_reg[3]),
print "cs:%2X" % (self.vm_cpu.vm_reg[cs]),
print "ds:%2X" % (self.vm_cpu.vm_reg[ds])
while 1:
self.execute(self.vm_cpu.vm_ip)
def execute(self,ip):
if (ip>(len(self.mem)-1)):
return False
opcode=self.mem[ip]
vm_opcode=GetOpcode(opcode)
vm_mod=ModDetect(opcode)
vm_operand1=GetOperand1(opcode)
#if vm_mod:
#vm_operand2=self.mem[ip+1]
vm_operand2=self.mem[ip+1]
self.vm_cpu.vm_ip+=2
if vm_opcode==0:
if vm_mod: #jmp`
if vm_operand2>=0x10:
self.vm_cpu.vm_reg[cs]=0x10
print "%X %s` r%d:r%d" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
self.vm_cpu.vm_ip=self.vm_cpu.vm_reg[cs]*vm_segment_size+(vm_operand2-self.vm_cpu.vm_reg[cs])*vm_segment_size+self.vm_cpu.vm_reg[vm_operand1]
#self.vm_cpu.vm_ip=self.vm_cpu.vm_reg[vm_operand2]*0x10+self.vm_cpu.vm_reg[vm_operand1]
else: #jmp
print "%X %s r%d" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1)
self.vm_cpu.vm_ip=self.vm_cpu.vm_reg[cs]*vm_segment_size+self.vm_cpu.vm_reg[vm_operand1]
elif vm_opcode==1:
if vm_mod: #movr`
print "%X %s` r%d,%X" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
self.vm_cpu.vm_reg[vm_operand1]=vm_operand2
else: #movr
#print "%X %s r%d,r%d" % (opcode,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
print "%X %s r%d,r%d" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
self.vm_cpu.vm_reg[vm_operand2]=self.vm_cpu.vm_reg[vm_operand1]
elif vm_opcode==2:
if vm_mod==False: #movm
print
"%X %s r%d,[ds:r%d]" %
(self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
self.vm_cpu.vm_reg[vm_operand1]=self.mem[self.vm_cpu.vm_reg[ds]*vm_segment_size+self.vm_cpu.vm_reg[vm_operand2]]
else: #movm`
print
"%X %s` [ds:r%d],r%d" %
(self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
self.mem[self.vm_cpu.vm_reg[ds]*vm_segment_size+self.vm_cpu.vm_reg[vm_operand1]]=self.vm_cpu.vm_reg[vm_operand2]
elif vm_opcode==3:
if vm_mod: #add`
print "%X %s` r%d,%X" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
self.vm_cpu.vm_reg[vm_operand1]+=vm_operand2
else: #add
print "%X %s r%d,r%d" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
self.vm_cpu.vm_reg[vm_operand1]+=self.vm_cpu.vm_reg[vm_operand2]
elif vm_opcode==4: #xor
if vm_mod:
print "%X %s` r%d,%X" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
self.vm_cpu.vm_reg[vm_operand1]^=vm_operand2
else:
#print "%X %s r%d,r%d" % (opcode,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
print "%X %s r%d,r%d" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
self.vm_cpu.vm_reg[vm_operand1]^=self.vm_cpu.vm_reg[vm_operand2]
elif vm_opcode==5:
if vm_mod: #cmp`
print "%X %s` r%d,%X" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
if(self.vm_cpu.vm_reg[vm_operand1]==vm_operand2):
self.vm_cpu.vm_flag=0
elif(self.vm_cpu.vm_reg[vm_operand1]>vm_operand2):
self.vm_cpu.vm_flag=1
else:
self.vm_cpu.vm_flag=0xff
else: #cmp
print "%X %s r%d,r%d" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
if(self.vm_cpu.vm_reg[vm_operand1]==self.vm_cpu.vm_reg[vm_operand2]):
self.vm_cpu.vm_flag=0
elif(self.vm_cpu.vm_reg[vm_operand1]>self.vm_cpu.vm_reg[vm_operand2]):
self.vm_cpu.vm_flag=1
else:
self.vm_cpu.vm_flag=0xff
elif vm_opcode==6:
if vm_mod: #jmpe`
print "%X %s` r%d,%X" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1,vm_operand2)
if self.vm_cpu.vm_flag==0:
#far jump
if vm_operand2>=0x10:
self.vm_cpu.vm_reg[cs]=0x10
self.vm_cpu.vm_ip=self.vm_cpu.vm_reg[cs]*vm_segment_size+(vm_operand2-self.vm_cpu.vm_reg[cs])*vm_segment_size+self.vm_cpu.vm_reg[vm_operand1]
else: #jmpe
print "%X %s r%d" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode],vm_operand1)
if self.vm_cpu.vm_flag==0:
self.vm_cpu.vm_ip=self.vm_cpu.vm_reg[cs]*vm_segment_size+self.vm_cpu.vm_reg[vm_operand1]
else:
#len 1
self.vm_cpu.vm_ip-=1
elif vm_opcode==7:
print "%X %s" % (self.vm_cpu.vm_ip,vm_instructions[vm_opcode])
print "".join(["%c"%self.mem[i] for i in range(0,len(self.mem))])
# print "%c" % (self.mem[i])
exit()
else:
print "unrecognised opcode"
exit()
print "ip:%3X" %(self.vm_cpu.vm_ip),
print "fl:%2X" % (self.vm_cpu.vm_flag),
print "r0:%3X" % (self.vm_cpu.vm_reg[0]),
print "r1:%3X" % (self.vm_cpu.vm_reg[1]),
print "r2:%3X" % (self.vm_cpu.vm_reg[2]),
print "r3:%3X" % (self.vm_cpu.vm_reg[3]),
print "cs:%3X" % (self.vm_cpu.vm_reg[cs]),
print "ds:%3X\n" % (self.vm_cpu.vm_reg[ds])
return True
vm=VirtualMachine(mem)
-----------------------------------------------------------------------------------------------
The important part of the output is listed at the very bottom.
GET /da75370fe15c4148bd4ceec861fbdaa5.exe HTTP/1.07z
By now you should know what to do with that...
*Stage Two Solution: http://canyoucrackit.co.uk/da75370fe15c4148bd4ceec861fbdaa5.exe
[+] Stage Three
---------------------
So you just downloaded the .exe file
from the Stage Two solution. This level, in my opinion, was the hardest
part. This is also where some of those requirements I listed above come
in handy. I renamed the .exe file to stagethree.exe just to make it
easier. First off, I opened up stagethree.exe in my hex editor. I
scrolled down back all the semi-non-important data until I found what I
was looking for.
hqDTK7b8K2rv..keygen.exe...usage:
keygen.exe hostname..r.license.txt..error: license.txt not
found..%s..loading stage1 license key(s).......loading stage2 license
key(s)......error: license.txt invalid...error: gethostbyname()
failed..error: connect("%s") failed..GET /%s/%x/%x/%x/key.txt
HTTP/1.0.....HTTP/1.0.....request:..%s.error: send() failed..response
I was right to rename the .exe file,
but the correct name is keygen.exe. Judging by the above code from the
hex dump, you can tell keygen.exe takes hostname as a parameter, reads
license.txt (which should hold a key from stage1 and another key from
stage2.) In the beginning of the code inspection we also see 'gchq'. I
thought that was interesting so let's keep that around for a while.
Scrolling down further in the hex reveals that the .exe file relies on
Cygwin DLLs for encryption/decryption. We can also tell by the code that
once the correct license.txt file is supplied the application makes a
request to: hostname/%s/%x/%x/%x/key.txt
Examining the code further the license.txt format appears below as:
Four Bytes - 8 Bytes - 4 Bytes - 4 Bytes - 4 Bytes
gchq is four bytes and was found in the
beginning of the code so let's give that a shot. This was really just
an incredibly lucky guess that turned out to be correct.
This is where the hqDTK7... string
comes in handy. The code next uses that string has a salt for an 8 byte
password. The solution to that cracked hash is cyberwin (8 bytes).
Giving us gchqcyberwin.
Now, it's obvious that we need three
more keys to finish the license.txt and get the application to complete
our request. The application itself gives me 2 very obvious clues by
saying 'stage1 license key(s)' and 'stage2 license key(s)'. What did we
skip over from the first two stages that might be the keys to this
puzzle?
In Stage One, at the very beginning of
the supplied code, the instructions jump over exactly 4 bytes.
0xa3bfc2af. Also, in Stage Two, the variable of 'firmware' is completely
unused in the VM emulation and gives us two more four-byte codes.
0xd2ab1f05 and 0xda13f110.
gchq + cyberwin + 0xa3bfc2af + 0xd2ab1f0t + 0xda13f110
OR
hqDTK7b8K2rv + 0xa3bfc2af + 0xd2ab1f0t + 0xda13f110
will give us the solution for: GET /%s/%x/%x/%x/key.txt
Trying the obvious, let's input that exact keys into each respective slot of the URL and try to vist
canyoucrackit.co.uk/gchqcyberwin/0xa3bfc2af/0xd2ab1f0t/0xda13f110/key.txt
Nope, not it. Damnit.
Next I tried it by replacing gchqcyberwin with the hash for that same key.
canyoucrackit.co.uk/hqDTK7b8K2rv/0xa3bfc2af/0xd2ab1f0t/0xda13f110/key.txt
Still no luck.
After trying various seemingly random
combinations of URLs and changing the order of variables, I eventually
landed on the right answer.
For each of the last 3 keys, you need to remove '0x' from the beginning of the string.
Giving you the final answer of:
/hqDTK7b8K2rvw/a3bfc2af/d2ab1f05/da13f110/key.txt
Throw that string behind canyoucrackit.co.uk and we have a winner!
http://canyoucrackit.co.uk/hqDTK7b8K2rvw/a3bfc2af/d2ab1f05/da13f110/key.txt
That URL will return the string: Pr0t3ct!on#cyber_security@12*12.2011+
Return to the main CanYouCrackIt URL, enter that string in the password prompt and enter.
You'll be directed to canyoucrackit.co.uk/soyoudidit.asp
Following that link, you get directed to the GCHQ career application page. Bravo!
If you like my blog, Please Donate Me