B1ll_Gat35
Problem
Can you reverse this Windows Binary?
Solution
Stage 1: Analysis
Reverse the binary file using Ghidra (cheat sheet).
main()
function:I found
main()
by going toSearch > Program Text
and searching forInitializing
in "All Fields" since that was a string that appears when the program launches. Clicking the one with the "PUSH" in the preview goes right to themain()
function.This is difficult to read but
thunk_FUN_00407f60()
appears to validate the key. If this function returns 0 then the key is incorrect, otherwise the key is correct.
Option 1: Patching the binary
In this option we rewrite a single character of the assembly of the program to run the code to print the flag even if the key is incorrect.
During the analysis stage we saw this
if else
block:If the function that checks the key we input returns 0 then the key is incorrect and we don't get a flag. Let's change that so if it returns 0 it jumps to the else block instead. We can do this quite easily thanks to Ghidra.
We are looking for the line
00408114 75 0f JNZ LAB_00408125
in the assembly view. This can be easily found by clicking on theif
of the if statement (which was discussed in step 1) in the decompiled view. This will highlight the correct line.The line directly before the aforementioned line contains the
TEST
operation:00408112 85 c0 TEST EAX,EAX
. What's important to know about theTEST
operation is that it sets the flagsCF
andOF
to zero. You can learn more on [its wikipedia entry](https://en.wikipedia.org/wiki/TEST_(x86_instruction)). JNZ jumps to the specified location if the Zero Flag (ZF) is cleared (test for something not being equal). If we change theJNZ
operation to theJNC
operation, which is true ifCF=0
, then we will skip right to the else block. Remember, the CF flag is always zero after theTEST
operation so the else will always run. In fact, the decompiler view doesn't even show it anymore after we make the change, as you will see in the next step. More info about all the operators related to JNZ can be found on this page.The make the above change, right-click on the
JNZ
operator, choose "Patch Instruction", and change theJNZ
toJNC
. The decompiler view will update to the following:To recap, we changed the line from
00408114 75 0f JNZ LAB_00408125
to00408114 75 0f JNC LAB_00408125
.Next, we need to export the program from Ghidra. Go to
File > Export Program
and set the "Format" to "Binary". Select your desired save location and click "OK". Now rename the exported file fromwin-exec-1.exe.bin
towin-exec-1.exe
(remove the ".bin").Now, we can just run the executable with
wine win-exec-1.exe
(modified executable: win-exec-1_patched.exe):
Option 2: Debugging to find the key
thunk_FUN_00407f60()
function from Ghidra:thunk_FUN_00407f40()
appears to get the key. This function points tothunkFUN_00407e30()
, which references a global variable calledDAT_0047c280
with address0x0047c280
. The last 4 values are the offset we want:c280
.Next, we open the program in Ollydbg. I pressed "Execute till return (Ctrl+F9)" and typed
1
in the program. Then, I hit "Pause execution (F12)", pressed the enter key, and then pressed "Execute till return (Ctrl+F9)" until the prompt for the key appeared. Now there are two options. You can disable ASLR on the binary using a method from this StackOverflow answer and then press CTRL+G and paste the offset,0xc280
, we found. This will bring you to the value of the key. However, the easier option is to simply use the debugging step features and list all strings.To do the second option, first make sure you are on the
win-exe
module (click "Show Modules window (Alt+E)" and choosewin-exe
to make sure) and thenright-click > Search for > All referenced text strings
as shown in the image below.You will see
The key is: 4253360
atPUSH 0F3C280
(probably different first two characters because of ASLR).Now just type the key into the program and hit enter to get the flag. Make sure to enter
The key is: 4253360
, not just4253360
.
Flag
PICOCTF{These are the access codes to the vault: 1063340}
Last updated