Thursday 3 October 2013

Sharif CTF Quals 2013 - Reverse 200 - Reverse200

Task:
Download
We are provided with an x86 ELF executable that crashes while trying to decrypt a key.


Probably we should patch the program or understand how to get a flag. Let's see assembly. There is no congratulation message among strings or anything that will show that we should reach that peace of code. However there are couple noteable strings: a string "Press any key to exit..." that is probably lies on the goal path or will lead somewhere and some base64 encoded string. The logic of the program is quite straightforward if you throw everything irrelevant away.

Firstly it copies base64 encoded string on the stack.



Then calls a function that takes a pointer to this string, an integer and some address. After examining that function you might have probably understood that it decodes input string from Base64 and second argument is a length of the base64. So I called it (from_base64). It returns a pointer to the decoded string and stores length of decoded string in the third argument address. There are couple of hints why it decodes base64.
1) It accepts base64 encoded string. So it is obvious that it may decode it.
2) It checks for input length being a multiple of 4.
3) It checks for '=' characters, which is used in Base64.


As a result you may notice some strange behavior. Size of the input string is constantly 1 , which is not correct. We will change this a bit later.

Next, the decoded string is passed to the two functions which modify the string, which I called xor_with_i and minus_five.


First one XORes each character with its index in string. However you may notice another strange thing. [ebp+i] should be a big value to leave the loop, but in our case i shouldn't be more than 0x21. That is another thing we will change a bit later.


Second one subtracts a reminder of 5 divided by [ebp + i]. There is another bug [ebp+i] is initialized with 0 and therefore first idiv instruction will throw divide by zero exception. We will need to do something here too.


Let's patch our binary. By the way you can probably write a script that will do required transformations, but patching is more interesting. A good way to do this is to use OllyDbg. You need to find location of the patched command (Ctrl + F) and then press Ctrl + E to modify command. Then run it and get the flag. After that you may commit changes or leave it broken. You need to change the following parts:
1) push 1 -> push 2c before from_base64 call
2) cmp [ebp + i], 2faf080h -> cmp [ebp + i], 21h in xor_with_i
3) mov [ebp + i], 0 -> mov [ebp + i], 1  in minus_five (It was luck that I've tried that way)



 After patching we can see such output:


So the key is: "D1am0ndGr33tsY0uW1thAW4rmW3lc0m3"

No comments:

Post a Comment