The Startup
Published in

The Startup

Hacking Series Part 9

Challenge: B1ll_Gat35

Category: reverse engineering

We are given a windows executable called “win-exec-1.exe”. When you run the exe, it asks for a number between 1 and 5 digits long. After you input a number, it prints “Initializing…” then asks for a correct key for the access codes. If the key is correct, you get the flag, and if the key is wrong, the program exits.

When I opened the binary in IDA I saw that there was a lot of obfuscation. None of the typical C functions were named, and there were many sub processes that jumped to other sub processes that jumped to others, and so on. In fact, majority of the assembly and called sub processes in the starting point were completely useless. The list of these sub processes totaled to almost 3000.

The first thing to do was to find the one function that was likely handling majority of the actual program logic. This was not hard, since I used the IDA debugger to set breakpoints after functions in start were completed. If the program did not stop before I could input a number, I moved the breakpoints higher up in the assembly until I found a function that stopped execution. This function was near the end of start, and I renamed it accordingly.

The reason I named it input_digits_and_flag_func was because when I looked inside, I saw a jump to another function, then I saw the program logic we needed.

When I was looking over this function, I realized that majority of it is meaningless obfuscation again. There are calls to functions that essentially do nothing. Even the “initializing” stage is likely to not be an influencing factor on the key, since there are multiple functions after the key is inputted that determine if the flag is printed or not. In total, three functions likely influence the key.

I've renamed these to func_1, func_2, and func_3. At the end of these, only the lower bit of eax from the result of func_3 determines if the flag is shown. This bit has to not be zero. If you look inside func_3 , you will see that there is only one case where this is possible.

Two out of the three results from this function change al to 0. One of the results changes al to 1. If we follow this path up, we get the logic we need for func_3 to result in al equaling 1.

Eax has to be below or equal to ebp+var_4, which is set to 0 above. So, eax has to be below or equal to 0 for us to get the needed result. You could go back and figure out what func_1 and func_2 do, then craft your input to get this result, but that would take a lot of time. Not to mention, there is a lot of meaningless obfuscation, so trying to figure out what those functions do by simply analyzing the assembly would be very hard.

Instead, I chose to put a breakpoint in the cmp instruction above, then ran the program with multiple inputs. I tried to see how the many inputs I gave the program influenced eax at this stage, and what could potentially make it 0. I realized that at this breakpoint, eax contained the number of digits that I inputted as the key.

So if I inputted 1234567, eax would contain 7 since that number has 7 digits. Since we need eax to be 0, instead of inputting a number, I just hit enter. I saw that eax now equaled 0, and I continued execution until I got the flag.

PICOCTF{These are the access codes to the vault: 1063340}



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store