13,233 views
Reversing 101 – Solving a protection scheme
Introduction:
In this post, we’ll look at an application reversing challenge from HTS (hackthissite.org) resembling a real-life protection scheme. You can find a copy of the challenge here: http://www.hackthissite.org/missions/application/app17win.zip
Put simple, the program creates a key for your username, and compares it to the one you enter.
This tutorial is not meant as a spoiler for HTS since for every username a dedicated password will be computed. This tutorial is purely written to allow you to understand how some (even real-life) protection schemes are implemented.
The goal of the HTS challenge is to create a key generator, but in this tutorial I just want to find out my own dedicated password.
Note: the length of the password is NOT static, and there are no anti-debugging mechanisms in effect :-)
I used Windows XP SP3, so if you have a different windows version the addresses may be different as well.
Thanks to HTS, and thanks to NightQuest for coding this nice application.
Run the application:
Z:\HTS\app17win>app17win.exe
******************************************
* HackThisSite Application Challenge #17 *
* Coded by NightQuest - 02-14-2009 *
******************************************
Objective:
You need to create a key that is unique to your HackThisSite username.
The idea is to create a keygen, but any method is allowed.
An example would be:
Username: SomeUserName
Password: HTS-1234-5678-9012-3456
Username: fancy
Password: **********
Username: fancy
Password: ****
Username:
As you can see, when you supply the wrong password, you’ll be asked to input your username again!
Find the password:
Start the program (inside the debugger right away), enter your username and an arbitrary password. Do NOT press enter after entering the password. The idea is to use the debugger to “hook” into the execution flow at this point, and see what happens.
Username: fancy Password: 123456
Press the pause button (or press F12) in the debugger (OllyDbg or Immunity Debugger) to interrupt the execution. Next, press Alt-F9 (return to user). This will tell the debugger to break as soon as it returns from any Operating System code and starts executing code from the application itself again.
The process should now be running again. Open the command prompt and press enter. You’ll notice that the debugger will intervene and pause the process again right after a call to kernel32.ReadConsoleInputA
The idea now is to continue to step through the application, and try to see where our input was used. Let’s use F8 (step over) to step through the instructions at this time. F8 will step over CALL instructions (to keep things a bit easier at this point), but we do need to keep an eye on the stack, every time we’re about the execute a CALL.
In fact, whenever reaching a CALL instruction, before pressing F8, check the stack and see if we can see our username and password on the stack.
Press F8, and you should find this “magic call”:
00402210 E8 8AEEFFFF CALL app17win.0040109F ; # magic call
Why is this the “magic” call?
Well, not only does it use the input, but also returns a value in eax. It basically sets AL to 1 if a wrong password is given. When it returns AL=0, the “TEST AL,AL” would set the zero flag, so the “JNZ” instruction below would not be taken. The app will then tell you: “Congratulations! Enter that password on HackThisSite.
Let’s evaluate what happens inside this call. Instead of setting over the call with F8, use F7 to step into the call.
Then use F8 to step until you reach 0x004012B2. This is where AL is set to 1 (indicating the password is wrong). You’ll notice that the routine jumped directly to the MOV AL,1 instruction, and didn’t execute the XOR AL,AL and JMP just above it:
Anyways, AL is set to 1, but we we should avoid this !!! In fact, we should try to make the application jump to
004012AE 32C0 XOR AL,AL
There are a lot of compare functions in this routine, and a lot of things are going on.
Let’s set a breakpoint at the magic CALL at 00402210, restart the application and enter a password in the format suggested by the application. In fact, you’ll need to use your hackthissite.org username.
I used “fancy” before, but my real username is “fancy__004”, so that’s what I’ll use from this point forward :)
Username: fancy__04 Password: HTS-1234-5678-9900-1122
When the breakpoint at 0x00402210 gets hit, we can enter the function again with F7 and step through the routine.
You’ll see that there’s a a lot of calls to this function:
004011B3 E8 68150000 CALL app17win.00402720
By stepping into this function you’ll see that there’s a lot of computing done. To understand the algorithm behind calculating the password you have to examine this function.
But I’ll continue since I just want to have my password.
We will encounter 2 compare functions which are not important to us, like this one:
But then this compare function is interesting:
Why is this compare interesting?
If you follow the jump which is taken when these values are not equal, AL is set to 1 (remember: we need AL = 0) and then the function returns.
So here we have a compare of the values 10 and 12.
Note: it’s in hex, in decimal it is: 16 != 18
So what does that mean??
Well, based on the input we provided (the username & password), we can derive this relationship:
- 16 = the number of digits in the password
- 18 = twice the number of characters of your username
Since my username has a fixed length, maybe the password is too short?? Let’s add some digits, according to the password convention, and use this password:
Password: HTS-1234-5678-9900-1122-00
Restart the application, use the “new” password and stop again at the same location:
This time, we pass the test. Good !!!!
Let’s recap real quick. The following compare instruction validates if the number of digits in the password is correct:
004011BA 3BF8 CMP EDI, EAX
Let’s step further. The next interesting compare is this one:
Why is this compare interesting?
Again if the values don’t match we take the jump to the instruction setting AL = 1.
What’s compared here?
- 12 = first 2 digits of my password: HTS-1234-5678-9900-1122-00
- 11 = ??? Maybe the real digits of the password? I think so :-)
So, in short: this instruction validates 2 digits in the provided password by comparing what I entered with what the application has computed.
0040128C 3B75 94 CMP ESI,DWORD PTR SS:[EBP-6C]
Let’s set a breakpoint at this location, restart the app and only change the corresponding part of the password. Since we know the first 2 digits should be 11, we simply update the password and replace 12 with 11.
When using password HTS-1134-5678-9900-1122-00, the compare will pass:
Excellent. Press F9 to let the application to run, and the breakpoint will get hit a second time.
This time, it shows the next 2 digits from the password, and it indicates what the calculated value is. Based on that info, we know that the next 2 digits of the password should be 28
Restart the application again, and change the next 2 digits, so the new password would be HTS-1128-5678-9900-1122-00 this time.
Since the calculated values can be seen at the breakpoint, we can now manually generate the entire password, 2 digits at a time:
HTS-1128-5678-9900-1122-00
HTS-1128–5678-9900-1122-00
HTS-1128–5678-9900-1122-00
HTS-1128–5678–9900-1122-00
HTS-1128–5678–9900-1122-00
HTS-1128–5678–9900–1122-00
HTS-1128–5678–9900–1122-00
HTS-1128–5678–9900–1122–00
Let’s validate if this works. Let’s enter the following credentials:
Username: fancy__04 Password: HTS-1128-2320-040D-2903-18
Z:\HTS\app17win>app17win.exe
******************************************
* HackThisSite Application Challenge #17 *
* Coded by NightQuest - 02-14-2009 *
******************************************
Objective:
You need to create a key that is unique to your HackThisSite username.
The idea is to create a keygen, but any method is allowed.
An example would be:
Username: SomeUserName
Password: HTS-1234-5678-9012-3456
Username: fancy__04
Password: **************************
Congratulations! Enter that password on HackThisSite.
w00t.
© 2012, Corelan Team (fancy). All rights reserved.