Solving B1ll_Gat35 from picoCTF
Hello there! Today we have another picoCTF challenge. This challenge can be found in the picoGym under Reverse Engineering and is named B1ll_Gat35. We can download the file and get started. I used Ghidra and Ollydbg201(2.01 or 201, however you wish to write it, is a fantastic version of Ollydbg) to solve this challenge. Lets see what this program does!
So you download a binary/Portable Executable(PE) file and can give it a run. The output is seen above. It asks for a number between 1 and 5 digits, then it asks for some sort of key. Seems password was not said key…darn. Lets load it into Ghidra and see what we get.
To find important code quickly, I initiated a “Program Text” search in Ghidra’s CodeBrowser(Ctrl+Shift+E) and the results are seen in the above picture. I double clicked the address under the “Location” and it took me to the function in the picture below.
You can now see the code in Ghidra’s decompiler. There are a couple of familiar sights like, “S_Input_a_number…”, “s_Initializing”, and “s_Enter_the_correct_key…”. One unfamiliar sight is in the “else” body of code, “s_Correct_input._Printing_flag:…”. We haven’t seen this output from our program yet but it looks promising. Through out this code there are comparisons and multiple function calls that can be seen by looking at the decompiler view and the disassembly view in Ghidra. I found myself sort of in a rabbit hole of double clicking these function calls only to be led to another function and on and on. So I sat back and thought about the big picture of the program. It asks for a number, then goes on to ask for a key, and if the key we enter is correct, it will grant us the access codes but if the key we enter is incorrect we are denied. The simple logic can be seen below.
What if we could turn this conditional statement into an unconditional statement and jump to the code that runs when the user has entered the correct key. This logic is seen below.
This brings to mind a technique called patching, where one can modify instructions to get their desired output/result. So lets load this program in Ollydbg and see if we can patch an instruction.
I searched for our familiar strings in Ollydbg, double clicked and was taking to the function that contains our important code. This code is seen below.
So now we see what’s happening in this program. We see a “TEST EAX, EAX” at 0x00148114 followed by a conditional jump “JNZ SHORT 00148125”. The instructions highlighted in green is where we want to go and the pink is if the entered key is wrong. So I put a breakpoint at 0x00148114(just right click on the instruction -> breakpoint -> select hardware/software), ran the program(F9), entered a number and then entered the passcode. Execution stops on our breakpoint and doesn’t execute the “JNZ” yet. So lets patch this “JNZ” and make it an unconditional “JMP”. Right click the instruction, erase the “JNZ” and replace it with “JMP”. Your patch should look like the picture below.
Run the program with F9 and check the result.
Awesome! Seems as if our patch worked! Lets make sure picoCTF oks it.
Alright! picoCTF says it is all good! Binary patching is very useful and can even be implemented to bypass malware armoring features. Hope you give this challenge a shot!