Tuesday, June 5, 2012

Defcon 20 CTF qualifiers: b200

On the second binary challenge, we have a copy of the server that is listening in one DDTEK servers. We need to find a way to get the key from it.

Basically, the program makes some sanity checks and starts a listener on port 18703, creating a fork process for each request to the server. On little problem here is that GDB on FreeBSD is not handling properly forking process, so you'll need to patch the binary to make easier the debugging proccess.

As you can see below, the main loop that handles the requests will create a fork'd process that will call the function "ptrCheckSolution" (0x08049460)
.text:08049344 mov     [esp], ebx      ; fd
.text:08049347 mov     dword ptr [esp+4], offset ptrCheckSolution ; int
.text:0804934F call    mainRecvLoop

Click me to expand

It seems that we need to analyze that function (0x8049460). Basically it's divided in the folllowing steps:
  1. Check if some "magic" values were sent
  2. Get the length of 2 variables (maximum of 400bytes each). After that, the application will read the 2 variables with the size that we specified before
  3. Do some calculations and if everything is ok, the "key" file will be sent. Otherwise. a "sorry\n" message will appear on our console :(

Step 1) Check that valid "tokens" were sent

We'll need to send 4 words that the server is expecting. As you can see below, it's easy to spot the values from the assembly code:

.text:080494F6 mov     ecx, [ebp+fd]
.text:080494F9 mov     dword ptr [esp+8], 4 ; int (bytes to read)
.text:08049501 mov     [esp+4], eax    ; int
.text:08049505 mov     [esp], ecx      ; fd
.text:08049508 call    recvData        ; Read 4 bytes that we sent
.text:08049533 cmp     ebx, 0FE732D6Fh ; "Magic value #1"
.text:08049539 jnz     short loc_8049  ; "EXIT if magic value doesn't match

The "magic" values are the following: 0x94A4C265h, 0xFE732D6F,0xEEF814CB,0x6EC8A126

Step 2) Read our variables

The server will proceed to read the size of the 2 values that we are going to be sent, checking that each value doesn't exceed 400 bytes

.text:0804960E call    recvData
.text:08049613 cmp     eax, 4
.text:08049616 jnz     loc_80
.text:0804961C mov     eax, [ebp+size]
.text:0804961F cmp     eax, 400h
.text:08049624 ja      loc_8
After that, both values will be read, checking that both of them has the same length, but with different values.
.text:0804969C cld
.text:0804969D cmp     eax, eax
.text:0804969F mov     esi, ebx
.text:080496A1 mov     ecx, eax
.text:080496A3 repe cmpsb
.text:080496A5 jz      loc_80494CD     ; "Are different the values? If not, go to error"

Step 3) Mathematical calculations

If the previous checks were ok, the server will proceed to do some complex calculations on each variable that we sent. After that, it'll check that the result of the calculations were the same for both values.

.text:080496DB call    tangleHASH  ; <= "Complex calculations here"
.text:08049715 call    tangleHASH  ; <= "Complex calculations here"
.text:08049722 mov     esi, [ebp+var_124]
.text:08049728 mov     ecx, 20h
.text:0804972D mov     edi, ebx
.text:0804972F cld
.text:08049730 repe cmpsb   ; 
.text:08049732 jnz invalidValues ; "Exit if both values are identical"
If you take a look on the function that is doing the complex calculations, you'll see plenty of "hardcoded" values.

.text:0804A24B mov     [ebp+var_498], 14B62D86h
.text:0804A255 mov     [ebp+var_494], 31CF379Ch
.text:0804A25F mov     [ebp+var_490], 1BC6382Ah
.text:0804A269 mov     [ebp+var_48C], 752E03B3h
.text:0804A273 mov     [ebp+var_488], 0D0346A2Ah
.text:0804A27D mov     [ebp+var_484], 0A1DC5B93h
.text:0804A287 mov     [ebp+var_480], 0F9BB11D2h
.text:0804A291 mov     [ebp+var_47C], 0EB6A9A40h


If you search some of this "hardcoded values" on Google, you'll discover that it seems to be the assembly code of "the Tangle Hash function". So it seems that we need to find two different strings that have the same value. In other words... we need to find a collision on this algorithm... That might need some time :(.

However, doing a bit of research you'll find out that "Tangle" is a hash algorithm that was sent to the open competition that is searching for the next generation SHA-3 algorithm. As you can see here, it didn't pass the second round as it was vulnerable to collisiion attacks... exactly what we need :)

You can read the paper and try to implement the algorith OR you can do a quick search on Google in order to get an already implemented attack :p. Grab the code here. Take in account that you'll also require the reference implementation of Tangle (here).

After executing the files, you'll get a potential collision: Collision found in Tangle-256
Message 1:
Hash of message 1:
Message 2:
Hash of message 2:

Let's give it a try!...
$ perl -e 'print "\x94\xa4\xc2\x65\xfe\x73\x2d\x6f\xee\xf8\x14\xcb\x6e\xc8\xa1\x26\x28\x00\x00\x00\xc8\x19\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc8\x19\x00\x80\x00\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x00\x80"' | ncat 18703
437f085141d357c5d28850d5119aacb5   <== Solution!
Got it!. The solution to this challenge is 437f085141d357c5d28850d5119aacb5
Note: Copy of the Tangle implementation + collision program added here

No comments:

Post a Comment