Setup: They give you a compiled ELF binary that runs a program that prompts you for a password. It will tell you if you guessed correctly.
I was going to use this as a change to learn the Ghidra tool, with help from the article.
First problem: It's compiled to run on Linux Debian x86. I was doing it on a MacBook. So, it wouldn't run.
I noticed that Ghidra offers you the option to export the binary as C code (which makes sense, as part of Ghidra's reverse engineering is to convert a binary into assembly and slightly-more-readable C-like code). So, I figured I could just compile that to run on my Mac.
It didn't work though, since Ghidra exports an incomplete version of the code that uses some invalid types, and doesn't define all of its labels properly, which required a lot of manual work that was increasingly appearing like it would take too long.
So I figured I'd just run the binary in a Docker container. I found the Debian i386 version and pulled it down. (I had a long side diversion here getting a setup so I could edit files on my machine that would appear as I want in the Docker container, but the details are uninteresting besides this clever hack for getting the "copy file" command into your docker one-liner.)
So, I was able to run the binary.
Second problem: Somehow, it thought I was using a "debuguer" -- which I would be, at some point, but is strange, because I wasn't using one yet:
Don't use a debuguer !
I looked through the decompiled code to see where it might be doing this and found:
lVar1 = ptrace(PTRACE_TRACEME,0,1,0);
if (lVar1 < 0) {
puts("Don\'t use a debuguer !");
/* WARNING: Subroutine does not return */
abort();
}
Hm, okay, well that "if" statement maps to this part of the assembly:
0804868c 79 11 JNS LAB_0804869f
That is, according to this handy reference, "Jump if not sign." Well, whatever "sign" is, I want it to do the opposite -- change "JNS" to "JS", so it "jumps if sign" and skips that block -- the one that gives the mean message and exits the program.
I haven't figured out a good way to format that line, but 0804868c is the (hexadecimal) location within the binary, 79 11 is the hex version of the binary command itself, JNS the assembly term (just a mnemonic device) for that command, and LAB_0804869f is the argument passed to the command -- in this case, a label for where to jump to in the program.
According to that spec, the JNS command maps to 79, and if I want it to be JS, I need to replace it with 78. But...
Third problem: I don't have an easy way to edit binaries.
A convenient way to look at them is as a hex(adecimal) dump in a "hex editor", but I hadn't done that for a few months. Hex editors are useful because they show you the raw hex, the offset where it appears in the file, and, off to the side, the ASCII/text equivalent of that hex. Fortunately, I found this comment, showing how to repurpose my text editor, vim, to double as an easy hex editor. I can just open it up, edit the hex values, save, and it updates everything.
You can then run a utility, "gobjdump", to see the code as assembly and verify that e.g. JNS changed to JS as expected.
Fortunately, when I ran that edited binary, it did what I wanted: not accuse me of using a debugger, and proceed with the rest of the program.
The rest of the hurdles are similar: there's some if-test that can send the execution into a block that you don't want it to. Fortunately, this binary is structured ... stupidly, from a security perspective. It has that same kind of if-block for validating whether you entered the right password. Right afterward, if the check succeeded, it prints the password. Not your input, no -- it prints the correct password, which you can later validate on an unmodified run.
So, it's just a matter of tweaking the code so that the you always enter the block that outputs the password. (They were smart enough not to have the password itself appear as an obvious string in the binary, at least.)
Once I saw the output, I could submit it at the challenge site and very it was correct.
Now for something harder!
3 comments:
Thanks for sharing.
These types of reverse engineering challeges are not that much appealing to me because I am already at greater level
Well done for taking on your first Ghidra reverse engineering task! Solving the problem and delving into the complexities of code is always an exciting experience. In addition to demonstrating your aptitude for troubleshooting, your thorough tour is an encouragement to those who are interested in pursuing reverse engineering. Anticipating further insights from your next adventures in this intriguing sector. Finance Assignment Help Though it may not be relevant, congrats on successfully completing the reverse engineering task!
Post a Comment