Revealing secrets via anti-debugging bypass

Recently I decided to start solving crackmes.one challenges and publish my experience as series of write ups. The first one is simple crackme by miah which has a low difficulty score and seems to be perfect for introduction to the series.

After I have downloaded the zip archive and unziped it, file authforperk.exe (SHA256 6f65c2ef2a828dff2247c2c5a377c91cf6c1fedd93116e01544ecbd9f5234093) is the one that is going to be the subject of analysis. As always, let’s check for static properties of this PE64 executable first.

In the list of imported functions of KERNEL32.DLL, isDebuggerPresent immediately caught my attention. Other than that, everything looks as usual. After running the program, we can observe infinite loop asking for the right username and password. Let’s disassemble and decompile the program in Ghidra and try to figure out the flow and APIs that program is calling.

What I always do with these types of challenges is to search for notable strings/outputs and check where they are appearing in the code through cross referencing. As we can see in above photo, “Username Buddy Boy:” and “Password Buddy Boy: ” are two strings that are outputted in function FUN_140001290. This flow is a typical one: prompt user for username and password and then compare it with the secret. As I didn’t want to spend too much time on analyzing how and where the secret is contained, I decided to focus on function that does the comparison (memcmp). This is certainly going to appear as breakpoint during dynamic analysis.

But before we jump into it, let’s find that anti-debugging piece of code.

FUN_140001290 is the function that utilizes this API and checks if we have debugger attached. If we do, program ends with the message.

Now we’re clear what we have to do:

  1. Disable anti-debugging protection and
  2. Analyze memory during memcmp call to try to extract plaintext username and password.

For the task 1 we could also patch the binary by changing the program’s logic instead of changing the return value of isDebuggerPresent. But enough of talk, let’s fire up WinDBG and do some dynamics.

After we have launched an executable, WinDBG breaks and gives us a chance to analyze it a bit. First, let see which modules are loaded.

As we can see, two modules are of particular interest to us since they’re the ones that are implementing functions that we want to set breakpoints on: KERNELBASE (isDebuggerPresent) and VCRUNTIME140 (memcmp). We can set those breakpoints with

bp KERNELBASE!isDebuggerPresent
bp VCRUNTIME140!memcmp

Let’s run the program and hit the first breakpoint (isDebuggerPresent) at 0x7ffafe8c0020. What we want to do now is to disassemble those instructions and see the one that is of interest to us with u rip (disassemble 10 instructions from the instruction pointer):

movzx   eax,byte ptr [rax+2]

As we know from cdecl convention that EAX is the register that is usually holding the return value, by examining the memory at RAX+2 offset, we’re spotting that at 0xaae35b1002 there’s a byte holding the value of 0x01 and ready to be moved to EAX, meaning that isDebuggerPresent is about to return TRUE (debugger is present). To bypass it, let’s change it to 0 with

eb 000000aa`e35b1002 0x0

and continue with execution. Now that we have successfully bypassed the anti-debugging protection, we can input arbitrary username and password in the console. Let’s fill it with couple of 0x41s.

Now we hit memcmp breakpoint. Perfect time to examine its instructions and try to catch the comparison steps.

Easily we can spot CMP instruction: lower eight bits of EAX are holding pointer to our input. Let’s put the breakpoint at 0x7ffaef270ff2 and continue. Now that we hit the CMP, we can dump memory contents at 0xaae33ffad0 revealing username and password (miah/bigballs666).

Thank you for reading, happy reversing and see you next time with new challenge.

One thought on “Revealing secrets via anti-debugging bypass

Leave a reply to Argino Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.