HTB "Eat the Cake!" Challenge

An excellent write up of the 'Eat The Cake' challenge on HackTheBox.

HTB "Eat the Cake!" Challenge

Welcome to another tutorial on how to resolve a small reverse challenge from Hack The Box. The specified challenge is "Eat the Cake!", the exe file is cake.exe and we are going to reverse it.

As soon as it is disassembled, there seems to be something strange; IDA PRO informs me that the IAT has not been loaded or seems to be outside of the memory allocated for the program if I launch in debug I am in an internal function of an imported library, a little further on some cycle that rewrites a memory location where there should be some code. So I give a look on "program segmentation" and faint memories flow to my mind; something that I haven't seen for years attracts my attention, so I have another old tool to which I had to dust.

I launch the PeID tool, version 0.95, a packer, cryptos and compilers detector for PE files. At first look, I can't notice anything, but also the tool, can't identify the exe file (Nothing found *).

So, I decided to give a hard scan and...

...surprise, this time the tool identifies the UPX patcher. I remember the UPX patcher, is not so complex, but sometimes present some problem to unpack it.
Anyway, go on and try to dump... No, rest assured, I won't waste you hours trying to restore the original version of the software when I didn't. However, I present the approaches that I adopted in the attempt:

  • original upx packer/unpacker
  • lordpe
  • PeID (itself)

I'm not so good at restoring the OEP, but some autonomous tools have not been able to do the same, surely someone else who has solved this challenge has dumped it, but reaching the solution in the way you think is most comfortable is still a good goal, so I will describe my solution.

Ok, after these approaches I decide to go on with a full debug session. IDA PRO seems to give me so many problems, so I chose another debugger: ollydbg.
Before to start, I view some old tutorials and articles about how to work UPX packer (my skills are a little rusted, I'm many years that I don't reverse).
So, finally, I remember and apply the correct steps to leave the program in memory and debug without the original binary file. This would mean, that, considering how UPX work, every time I launch debug, the address generated in memory will be different, so I have to execute all the code without relevant breakpoint, so prepare to repeat the same steps for many many times, but let's not be discouraged.

Launching with ollydbg, the starting point of the program will be always the same (it stop the process at the same point).

The first instruction, a PUSHAD, load in the ESP the starting procedure where the rewriting procedure of the original code was restored. Here you can find a small loop and immediately after a jump to the starting program. To stop in the right address, anyway, step for a single instruction (F7 or F8), right-click on the ESP register, "Follow in Dump", select the our byte on the ASCII representation of the memory and set an "hardware break on write" of a word and continue to execute to arrive at that point (Like in the animation below).

Ok, if you are in the right place, you have to execute a small loop and then jump at the real entrypoint (let me call it so) to debug the real piece of code. To be fast, you can locate on the last line of code where the final jump will bring you at the start of the rewritten procedure (three-line after the point where you are landing) and press F4 (to execute all the loop) and after F7 or F8.

Well, I tried much time to understand which the next interesting function to follow, and after a lot of debugging session I arrive at this instruction:

009B24AA   E8 A1EEFFFF      CALL cake.009B1350

Run inside (F7) and take open your eyes. Here you can identify some known message.

If you execute the code straight on it will stop at this line of code:

009B1447   E8 94090000      CALL cake.009B1DE0

The program is asking for the 10 digit password. If you try the program as is (without debug) you can see that it asking for 10 digit password before and 15 digit password after..... have you try to pass a generic password of 15 digits immediate? Yes, the second message is ignored. If you specify then a 15 digit password the program take it as the answer to the second question. Then, also if the code asks for a 10 digit password you can insert a 15 digit password. To identify when the program elaborates our code, write something that you can identify immediately when showed, something like "123456789012345". When you press "enter" the code comes back to the debugger and you can go on with your session.

Well, execute not so fast and ee the code pass in front of your eyes. You should arrive at a code like this:

where I'd like to be attention on the strccpy instruction (used in c++ to put a string in a variable), the block immediately after and the messages at the end of the code.

Well, I want that you understand what I mean, then execute until the strcpy instruction and press F8 to execute also it.

Well done, after the instruction our 15 digit password is in the ECX register. The code after is really interesting, it check, char by char, in a spread order, the characters of our password, when it turns out wrong the code jump on the message "Better luck next time!". Well try to put the chars in the correct order and identify the letter it is checking. This is the original code:

009B14AA   83C4 10          ADD ESP,10
009B14AD   C68424 23040000 >MOV BYTE PTR SS:[ESP+423],0
009B14B5   8D4C24 24        LEA ECX,DWORD PTR SS:[ESP+24]
009B14B9   E8 32FEFFFF      CALL cake.009B12F0
009B14BE   807C24 27 6B     CMP BYTE PTR SS:[ESP+27],6B
009B14C3   8AD0             MOV DL,AL
009B14C5   75 34            JNZ SHORT cake.009B14FB
009B14C7   807C24 2C 61     CMP BYTE PTR SS:[ESP+2C],61
009B14CC   75 2D            JNZ SHORT cake.009B14FB
009B14CE   807C24 24 68     CMP BYTE PTR SS:[ESP+24],68
009B14D3   75 20            JNZ SHORT cake.009B14F5
009B14D5   807C24 2E 61     CMP BYTE PTR SS:[ESP+2E],61
009B14DA   75 19            JNZ SHORT cake.009B14F5
009B14DC   807C24 29 68     CMP BYTE PTR SS:[ESP+29],68
009B14E1   75 18            JNZ SHORT cake.009B14FB
009B14E3   807C24 2D 72     CMP BYTE PTR SS:[ESP+2D],72
009B14E8   75 11            JNZ SHORT cake.009B14FB
009B14EA   807C24 2F 64     CMP BYTE PTR SS:[ESP+2F],64
009B14EF   75 0A            JNZ SHORT cake.009B14FB
009B14F1   B0 01            MOV AL,1
009B14F3   EB 08            JMP SHORT cake.009B14FD
009B14F5   8A4424 0B        MOV AL,BYTE PTR SS:[ESP+B]
009B14F9   EB 02            JMP SHORT cake.009B14FD
009B14FB   32C0             XOR AL,AL
009B14FD   807C24 25 40     CMP BYTE PTR SS:[ESP+25],40
009B1502   75 1F            JNZ SHORT cake.009B1523
009B1504   807C24 32 45     CMP BYTE PTR SS:[ESP+32],45
009B1509   75 18            JNZ SHORT cake.009B1523
009B150B   807C24 26 63     CMP BYTE PTR SS:[ESP+26],63
009B1510   75 0B            JNZ SHORT cake.009B151D
009B1512   807C24 31 24     CMP BYTE PTR SS:[ESP+31],24
009B1517   75 04            JNZ SHORT cake.009B151D
009B1519   B1 01            MOV CL,1
009B151B   EB 08            JMP SHORT cake.009B1525
009B151D   8A4C24 0B        MOV CL,BYTE PTR SS:[ESP+B]
009B1521   EB 02            JMP SHORT cake.009B1525
009B1523   32C9             XOR CL,CL
009B1525   84D2             TEST DL,DL
009B1527   74 0D            JE SHORT cake.009B1536
009B1529   84C0             TEST AL,AL
009B152B   74 09            JE SHORT cake.009B1536

The correct order should be this...

00CD14CE   807C24 24 68     CMP BYTE PTR SS:[ESP+24],68
00CD14FD   807C24 25 40     CMP BYTE PTR SS:[ESP+25],40
00CD150B   807C24 26 63     CMP BYTE PTR SS:[ESP+26],63
00CD14BE   807C24 27 6B     CMP BYTE PTR SS:[ESP+27],6B
00CD14DC   807C24 29 68     CMP BYTE PTR SS:[ESP+29],68
00CD14C7   807C24 2C 61     CMP BYTE PTR SS:[ESP+2C],61
00CD14E3   807C24 2D 72     CMP BYTE PTR SS:[ESP+2D],72
00CD14D5   807C24 2E 61     CMP BYTE PTR SS:[ESP+2E],61
00CD14EA   807C24 2F 64     CMP BYTE PTR SS:[ESP+2F],64
00CD1512   807C24 31 24     CMP BYTE PTR SS:[ESP+31],24
00CD1504   807C24 32 45     CMP BYTE PTR SS:[ESP+32],45

mmmm..... some character is missing, but, don't worry, identify the characters and start to read what is available...


...if I replace the number with the relative char (68 = h, 40 =  @, 63 = c and so on)...

 h @ c k . h . . a r a d . $ E

I know, most of you are reading the hidden letters identifying the missing ones. Ok, but let me explain here you can find the rest of the chars.
There's a function after the strcpy, you have to enter inside and here are verified the missing letter, or at least two of the missing letter.

009B14B9   E8 32FEFFFF      CALL cake.009B12F0

The additional two chars verified are the "t" and the "p" letters that are the fifth and the eighth letters of the entire password, so, our secret word at this moment is:
h @ c k t h . p a r a d . $ E

Well, it's clear that the sentence is "hack the paradise", but knowing the hacking community, will be not a simple letter, but number that replaces the original letters, so I suppose the "e" or "E" letter was replaced by the number "3" and the "i" or "I" letter is replaced by the number "1".
Our final password should be [email protected]$E.

And also this challenge is done.

P.S.: Well, last part of the chars identification, is done by supposition, but, let me say that, sure you can turn around the code and you will find the last part of the verification process where is checked the two letter missing.

The awesome artwork used in this article is called Let Them Eat Cake and was created by Samuel B Thorne.