[KEYGENME - EASY] Cracking Your First Program

Not sure how to interpret that sentence… I’d say thanks… just in case

7 Likes

@dtm, I want to believe that you were too tired while typing that comment.

4 Likes

Right, I forgot the other half: though oftentimes better than master of one. I can’t confirm your masteries, I’d assume you have a few.

4 Likes

Would you be able to direct me to how you got there?

Sure

The easiest way is to use radare 2
Sorry about the image do not know how to make it bigger. it says:

$ r2 ./k
[xxxx] aa
[xxxx] pdf @main

You can see in the assembly how the program opens a file named ‘keyfile.dat’ and then reads its content using fread into memory. Then, the relevant part is:

|    .----> 0x080485f6      8d54241c       lea edx, [esp + 0x1c]       ; 0x1c
|    ||||   0x080485fa      8b442410       mov eax, dword [esp + 0x10] ; [0x10:4]=0x30002
|    ||||   0x080485fe      01d0           add eax, edx
|    ||||   0x08048600      0fb600         movzx eax, byte [eax]
|    ||||   0x08048603      3c74           cmp al, 0x74                ; 't'
|   ,=====< 0x08048605      741f           je 0x8048626
|   |||||   0x08048607      c70424fe8604.  mov dword [esp], str.Error:_Incorrect_key ; [0x80486fe:4]=0x6f727245 LEA str.Error:_Incorrect_key ; "Error: Incorrect key" @ 0x80486fe
|   |||||   0x0804860e      e8fdfdffff     call sym.imp.puts
|   |||||   0x08048613      8b442414       mov eax, dword [esp + 0x14] ; [0x14:4]=1
|   |||||   0x08048617      890424         mov dword [esp], eax
|   |||||   0x0804861a      e8c1fdffff     call sym.imp.fclose
|   |||||   0x0804861f      b801000000     mov eax, 1
|  ,======< 0x08048624      eb1d           jmp 0x8048643
|  |`-----> 0x08048626      8344241001     add dword [esp + 0x10], 1
|  | ||||   ; JMP XREF from 0x080485f4 (main)
|  | |`---> 0x0804862b      837c24100f     cmp dword [esp + 0x10], 0xf ; [0xf:4]=0x3000200
|  | `====< 0x08048630      7ec4           jle 0x80485f6

The first lines access the buffer one by one in a loop using a counter at [esp+0x10] and compares the value with the character ‘t’ (0x74). If any of the values is different it just prints the bad guy. Otherwise it jums ot 0x8048626 and increases the loop counter. When it reaches the value 0xf we are done and we get the success message.

I actually didn’t use radare2 but gdb… However explaining how to solve it with gdb will require a longer text. Radare does most of the work automatically :slight_smile:

4 Likes

Right I’m still not fully sure what you’ve done? Using a program called r2? I apologize since I’m an insane noob at RE but would love to be more proficient at it, especially in Linux.

1 Like

It’s radare2 and it’s an open-source RE framework. There is plenty of documentation around it and it’s on the rise. Quite of a pain in the ass to master it though.

Have a look at this link in case you are interested in getting started with it: https://blog.techorganic.com/2016/03/08/radare-2-in-0x1e-minutes/

1 Like

Sorry about that.

If @dtm is OK I can publish a more detailed explanation. I mean, maybe he wants to write such a paper himself.

As @_py mentioned below radare2 is a reverse engineering tool… it automates a lot of things and, in general, simplifies the whole process.

You’re more than welcome to write your analysis.

1 Like

That article is mostly good. although there appears to be a lot of handwaving on how he gets the password? He says that the disassembly of the function reveals what characters are required, where does it say the characters?

Yes, the characters are looking at you straight in the eyes.

cmp al, 0x74 ; ‘t’

1 Like

I’m referring to helloworld in that article you linked me.

Sorry. Took a little more looking :stuck_out_tongue: found it! Thanks. I was expecting a string or an array of sorts of chars.

I know you were expecting a string or an array of chars.

I have a question regarding a line in this challenge:

[spoiler]cmp dword [local_10h], 0xf

0xf is equal to 15 in decimal, so why did it take 16 t’s for the cmp to be true? I know hex is base16 and starts counting at zero but 0xF == 1111 == 15. Edit: I should clarify that I used Radare2. Also, a side question what does this line mean in r2? - ; [0xf:4]=0x3000200 it’s on the same line as the cmp.[/spoiler]

jle 0x80485f6

It will keep looping while it’s less or equal. Meaning, the counter will be in the range of [0,15] (note I didn’t type [0,15)), which in total is 16.

1 Like

I’m assuming the iterator starts at 0, please check if you’re making a fence post error.

1 Like

Quite an easy task :stuck_out_tongue:

You can find my solution below:

When starting the static analysis I spotted a few details which gave me plenty of information about the required key.

  • The binary seems to load the key from a file named keyfile.dat

  • The key length should be, at least, 16 chars

  • Each char is compared to the following value : 0x74 (’t’)

Consequently, we can assume that the key only contains ’t’ chars. After a quick dynamic analysis, the key length found was 17 chars.

=> Challenge completed.

Thanks for the challenge @dtm

2 Likes

My solution (Didn’t look at other posts):

echo tttttttttttttttt > keyfile.dat

1 Like

Nice warmup to get back into assembly

python -c “for i in range(0,15): print(‘t’, end=’’);” >> keyfile.dat

1 Like

what tool did you use here?