Hello All!
Sorry for such a lengthy delay in the release of this tutorial. I am currently modifying my schedule right now, but once things are worked out I should be able to roll out tutorials in a consistent manner. I'll give details on that when I get everything worked out =)
OK. Let us begin tutorial four. In this tutorial we are looking to practice what we previously learned in the first three tutorials as well as extend our knowledge on assembly. It is highly recommended to do the first three tutorials I released to follow along easily.
Step 1. The Crackme we will be using for this tutorial is called Keygenme1 by Sashx41. Like in the previous tutorials go to crackmes.de and login. Click on advanced search underneath the Crackme search on the left side of the website. Select the following options for search:
Step 2. When the results show, scroll down a little and look for Keygen #1 by Sashx41. This is the Crackme we are looking for. It should be the third or fourth one.
Step 3. Unpack the zip that is storing the Crackme and go ahead and open it in Ollydbg. Like our previous tutorials Ollydbg paused the program at its entry point.
Step 4. OK our strategy from the previous tutorials has not changed. We are going to run the program and get a feel for it. Remember, the purpose of this step is just to scout around for juicy details. So let us go ahead and run the program.
Step 5. When we run the program we are presented with three lines of text; something about the keygen and then two lines about how we are to move to the next step. The first of the two lines says to enter a name, and the second line says that the name must be 8 characters or greater in length. I don't think everyone was born with a name that exceeds or meets 8 characters, but let us make one up and enter it ;)
Step 6. So with our real name entered the program allows us to move to the next step. In this next step it asks us to enter a password. So let us enter our secret password:
Step 7. Yes. We will never give up on hoping to get the password correct on the first try! This marks the end of the program as there is nothing else to do. So our next step in our strategy dictates that we search the program for strings. So restart the program and load up the strings window. Recall, to load strings: 1) right click in disassembly window, 2) Search for, 3) All referenced strings.
Luckily for us there aren't a lot of strings in the window. I believe this is the only tutorial we have done so far that has an extremely small number of strings. But that's good. This makes our job so much easier. So like before let us look for something that looks like the 'goodboy' message. The string "Right password! You made it! Gratz, now upload your solution." seems closest to a goodboy message, so go ahead and double click on that one.
Step 8. Here is how Ollydbg should look once you double click on the goodboy message in the strings window.
Step 9. So we can see in the disassemble window that the goodboy and badboy message are a few lines away from each other. This makes me think that somewhere above the goodboy message there is code that is determining which message should be displayed. So what I am going to do in this instance is look for the little arrow that is pointing right in the machine code column. In the below picture I have a line selected that shows an arrow on it.
Ollydbg will sometimes help you with where JMPs lead to. This assistance is useful in this scenario because this code is very simple and we can quickly determine a place for testing. So if you click on the line that is selected in the picture, you can see that Olldbg shows us that a JLE takes us to this location. (Remember that JLE is a variation of JMP, JNE, JLE, JGE, JZ, and a bunch of otheres that begin with the letter J)
Step 10. We are going to use this location as a starting point to test the code and understand it a little. We could of course just start reading the code at this point, but seeing it run is somewhat more helpful since that can be faster then reading. And of course our assembly at this point isn't all that great =) So let us drop a break point on the line that has the JLE on it.
Step 11. Let's play with the program now! Go ahead run the program and perform the program duties until we hit the break point.
Step 12. Nice. Notice that the jump is not taken. The area that shows you this is where the big black Microsoft paint arrow in the above picture points to. So far this tells me that our random input doesn't affect this condition. This means that the badboy message is not going to be displayed by some incorrect guess. From this point on we are going to have to do some more research to see how this program works. So let us just F8 (step over) our way through.
We will quickly find our self in a loop. We can tell because Ollydbg has drawn a black line that is inside the assembly column. The picture below shows which line I am talking about.
Inside this loop there is a problem. There is a JNE that points to an area in code that is below the goodboy message. The area below the goodboy message just so happens to be the code for showing us the bad message. See the below picture for reference.
NOTE: The picture points at the line that the JNE takes us to. I'm not referring to the PUSH ECX assembly code. It's the red line you are looking for!
OK. So at this point in the tutorial I am going to branch off. There are many different ways to solve this Crackme from where we are now. I am going to show you some of these solutions with each being a different degree in difficulty. We will start with the easiest then work our way to the more involved solutions.
Recall the first break point we set:
Changing the program instruction at this point will be the easiest way to solve the Crackme. We can simply change the JLE to a JMP that lands us on the code immediately after loop exit.
The last line of the loop is a JL SHORT. The line immediately after this is the line after loop exit. All we must do is point our jump to this location. As you can see in the above picture I changed the assembly of the JLE SHORT 01011227 to JMP 01011212. The 01011212 is the line after loop exit.
After changing the assembly, continue (run) the program and it will yield this result:
Instead of changing the assembly line before the loop in this approach we are going to modify the jump line inside the loop. The reason I am showing this approach (even though it is inefficient) is because it will teach you more about assembly/programming. And we all know that in order to be a good reverse engineer you need very good knowledge of assembly.
I am going to quickly go over the solution then describe in detail why it works.
Step 1. Restart the Crackme in Ollydbg.
Step 2 If you added the patch from the first approach, remove it by selecting View > Patches > (right click on entry in patch window) Restore code.
Step 3. Drop a break point on the JNE SHORT which is inside the loop.
Step 4. Now let us change the line that the break point is on. Double click the line and make it a NOP.
Step 5. Remove the breakpoint from the line and then continue (run) the program. T
Step 6. Success!
Now that we see the magic let us introduce the science to understand how it works.
So all the science is in this loop. If we understand this loop, we will understand the password comparing process. We will even find the real password if we understand this loop (that will be the next approach).
Starting at the top of the loop is
For argument1 we have CL. This is a new piece of assembly that hasn't been introduced in any of the previous tutorials. So let's go through what this CL is. Warning: it will be a long journey to get there!
Recall in the second tutorial that we learned about the EBP register (which stands for the extended base pointer). The EBP register held data for the program to utilize. We can see what the register is holding by looking at the registers pane in the top right of Ollydbg.
You might also notice in that same pane a few other words that begin with the letter E. That's because there are multiple registers a program can use. You know about the EBP already. Let's name the other ones:
EAX
ECX
EDX
EDX
ESP
ESI
EDI
EBP
EBX
Each of these registers are used to hold data or some type of data throughout the programs lifespan. We won't go into detail for all of them because that will be to hard to remember for now. But what we do need to cover is that some registers can segment themselves into smaller pieces.
Each register is 32 bits in length, and we access the entire register via its full name e.g: EAX. However, if we wanted to access just 16 bits of EAX we use AX. And if we wanted to access 8 bits of the AX we use AL or AH. This can be seen in the naming; EAX means extended accumulator register, AX means accumulator register, AH means accumulator high, and AL stands for accumulator low.
Example:
MOV EAX, 0FCA1240 - moves 0x0FCA1240 into the register
MOV AX, 6F4A - moves 6F4A into the AX register
MOV AH, 6F - moves 0x6F into the upper 8 bits of the AX register
MOV AL, 3 - moves 0x3 into the lower 8 bits of the AX register
OK. Let's bring it all together now. We have a value being moved into CL. The CL is counter lower register. Its the subset of the CX register who is the subset of the ECX register. So we are moving 8 bits of something into this register.
Notice in the picture below we have 6F in the ECX register. 6F also fills the space for CL. Notice that CH is 00, CX is 006F, and the entire ECX register is 0000006F.
NOTE: For argument2 its highly likely that your memory address and value that you will be seeing will be different. You should be able to follow the steps along easily and replace the values I have here with the ones on your computer.
Now lets go over argument2. This is what is being pushed into the CL register. The argument reads: BYTE PTR SS:[EAX+ESP+10] Although there is a lot of stuff in it, it is very easy to break down. By seeing the SS: we know it is referencing the stack segment. This means our eyes want to be on the stack frame panel in the lower right section of Ollydbg.
The BYTE PTR tells us that we will be pulling a byte sized value off of the stack. What is inside the brackets tells us where on the stack we will be pulling the byte sized value. Inside the brackets we have EAX+ESP+10. If we add that up, it will give us the address of where to remove the value from. So let's do the simple math real quick. Looking at your registers pane (see above image), add the values in the corresponding registers:
EAX at the moment this program is running is 0.
ESP at the moment this program is running is 00BFF730.
And 10 is 10.
So load up your windows calculator and set it to programmer view.
This is the location on the stack we need to get the value from. BYTE PTR:SS[BFF740]. So look for BFF740 in SS: where SS: is the stack, and remove a BYTE PTR from the location.
We can see in the picture above that BFF740 is equal to 36373839. Since we only want a byte sized value (A byte is 8 bits. A byte is equal to two hexadecimal value e.g. F = four bits and FF = one byte) , we remove the 39 from the very right.
This concludes the explanation for the MOV CL, BYTE PTR:SS[EAX+ESP+10]. We can verify that it moves the value 39 into CL by stepping-over onto the next line and viewing the ECX register. The above picture shows this. Notice Ollybdg is now on the line after MOV CL, BYTE PTR:SS[EAX+ESP+10]. This means the previous line has been computed.
Now that was a lot of information. I hope this isn't overwhelming you! For the rest of the lines inside the loop I am not going to write a detailed explanation for those. I will do so on the next approach. Instead what I am going to write is how they work.
So what happens next in the loop is very simple. We are going to compare the value that was found and placed into CL versus another value on the stack (EAX+ESP+210). If these values match, then we are going to increment a counter (the counter is EAX) and remove another byte value from the stack and push it into CL. We won't be removing the same exact value from the stack but rather the number to the left of the one we had just used (the 39). We are going to repeat this until either the comparison fails, or the counter reaches the value of EDI.
If the comparison fails (CL does not match the value) then we are going to JUMP to the badboy message. This means the JNE SHORT inside the loop will be activated. Recall JNE means jump if NOT equal.
If the loop completes, the program will automatically run the path of showing the goodboy message.
From this information we can find an exploitable flaw. That is, as long as the JNE SHORT is never called then the program will always display the goodboy message. This is good information. This explains why the program gives the goodboy message when we placed a NOP in place of the JNE SHORT.
OK. I am going to cut the tutorial here and place the next approach in the upcoming tutorial. I really wanted to place it here, but I feel this is so much information for one to manage. On top of that this tutorial is already very lengthy. I do need to consider that you guys have other things to do =)
So in the next tutorial I will write about how to uncover the password, so that we do not have to patch the program. If you want some homework, then see if you can discover the password mechanism on your own, and enter an explanation in the comments below. Remember, the password mechanism is the loop itself.
Sorry for such a lengthy delay in the release of this tutorial. I am currently modifying my schedule right now, but once things are worked out I should be able to roll out tutorials in a consistent manner. I'll give details on that when I get everything worked out =)
OK. Let us begin tutorial four. In this tutorial we are looking to practice what we previously learned in the first three tutorials as well as extend our knowledge on assembly. It is highly recommended to do the first three tutorials I released to follow along easily.
Step 1. The Crackme we will be using for this tutorial is called Keygenme1 by Sashx41. Like in the previous tutorials go to crackmes.de and login. Click on advanced search underneath the Crackme search on the left side of the website. Select the following options for search:
Search Options |
Download this one |
Step 3. Unpack the zip that is storing the Crackme and go ahead and open it in Ollydbg. Like our previous tutorials Ollydbg paused the program at its entry point.
Opened and Paused. |
Step 4. OK our strategy from the previous tutorials has not changed. We are going to run the program and get a feel for it. Remember, the purpose of this step is just to scout around for juicy details. So let us go ahead and run the program.
Program Opened and Running |
Step 5. When we run the program we are presented with three lines of text; something about the keygen and then two lines about how we are to move to the next step. The first of the two lines says to enter a name, and the second line says that the name must be 8 characters or greater in length. I don't think everyone was born with a name that exceeds or meets 8 characters, but let us make one up and enter it ;)
Our name entered. |
Step 6. So with our real name entered the program allows us to move to the next step. In this next step it asks us to enter a password. So let us enter our secret password:
Password Entered |
Step 7. Yes. We will never give up on hoping to get the password correct on the first try! This marks the end of the program as there is nothing else to do. So our next step in our strategy dictates that we search the program for strings. So restart the program and load up the strings window. Recall, to load strings: 1) right click in disassembly window, 2) Search for, 3) All referenced strings.
Luckily for us there aren't a lot of strings in the window. I believe this is the only tutorial we have done so far that has an extremely small number of strings. But that's good. This makes our job so much easier. So like before let us look for something that looks like the 'goodboy' message. The string "Right password! You made it! Gratz, now upload your solution." seems closest to a goodboy message, so go ahead and double click on that one.
Text Strings Window |
Step 8. Here is how Ollydbg should look once you double click on the goodboy message in the strings window.
Goodboy Message Double Clicked From Strings Window |
Step 9. So we can see in the disassemble window that the goodboy and badboy message are a few lines away from each other. This makes me think that somewhere above the goodboy message there is code that is determining which message should be displayed. So what I am going to do in this instance is look for the little arrow that is pointing right in the machine code column. In the below picture I have a line selected that shows an arrow on it.
Spotting a JMP |
Ollydbg will sometimes help you with where JMPs lead to. This assistance is useful in this scenario because this code is very simple and we can quickly determine a place for testing. So if you click on the line that is selected in the picture, you can see that Olldbg shows us that a JLE takes us to this location. (Remember that JLE is a variation of JMP, JNE, JLE, JGE, JZ, and a bunch of otheres that begin with the letter J)
Step 10. We are going to use this location as a starting point to test the code and understand it a little. We could of course just start reading the code at this point, but seeing it run is somewhat more helpful since that can be faster then reading. And of course our assembly at this point isn't all that great =) So let us drop a break point on the line that has the JLE on it.
Drop a breakpoint here. |
Step 11. Let's play with the program now! Go ahead run the program and perform the program duties until we hit the break point.
Break Point Activated |
Step 12. Nice. Notice that the jump is not taken. The area that shows you this is where the big black Microsoft paint arrow in the above picture points to. So far this tells me that our random input doesn't affect this condition. This means that the badboy message is not going to be displayed by some incorrect guess. From this point on we are going to have to do some more research to see how this program works. So let us just F8 (step over) our way through.
We will quickly find our self in a loop. We can tell because Ollydbg has drawn a black line that is inside the assembly column. The picture below shows which line I am talking about.
The Loop |
Inside this loop there is a problem. There is a JNE that points to an area in code that is below the goodboy message. The area below the goodboy message just so happens to be the code for showing us the bad message. See the below picture for reference.
This line will spell our doom |
NOTE: The picture points at the line that the JNE takes us to. I'm not referring to the PUSH ECX assembly code. It's the red line you are looking for!
OK. So at this point in the tutorial I am going to branch off. There are many different ways to solve this Crackme from where we are now. I am going to show you some of these solutions with each being a different degree in difficulty. We will start with the easiest then work our way to the more involved solutions.
The Easiest Approach ---------------------------------------
So the easiest way of solving this Crackme will be a simple patch to the JLE that exists above the loop. Instead of entering the loop we can simply direct the program to the code after loop exit and we will see the goodboy message. Let us try this.Recall the first break point we set:
Our first Break Point |
Changing the program instruction at this point will be the easiest way to solve the Crackme. We can simply change the JLE to a JMP that lands us on the code immediately after loop exit.
Easy Jump |
The last line of the loop is a JL SHORT. The line immediately after this is the line after loop exit. All we must do is point our jump to this location. As you can see in the above picture I changed the assembly of the JLE SHORT 01011227 to JMP 01011212. The 01011212 is the line after loop exit.
After changing the assembly, continue (run) the program and it will yield this result:
Success! |
A Slightly More Involved Approach ------------------------------------------------
I am going to quickly go over the solution then describe in detail why it works.
Step 1. Restart the Crackme in Ollydbg.
Step 2 If you added the patch from the first approach, remove it by selecting View > Patches > (right click on entry in patch window) Restore code.
Step 3. Drop a break point on the JNE SHORT which is inside the loop.
Break Point Inside Loop |
Step 4. Now let us change the line that the break point is on. Double click the line and make it a NOP.
Step 5. Remove the breakpoint from the line and then continue (run) the program. T
Step 6. Success!
Successful NOP |
Now that we see the magic let us introduce the science to understand how it works.
The Loop Assembly |
Starting at the top of the loop is
MOV CL, BYTE PTR SS:[EAX+ESP+10]
Let's break the line down piece by piece. Recall the structure for writing an assembly instruction:
instruction argument1, argument2
For instruction we have MOV. Quick lesson recap: the mov instruction places what is in argument2 into argument1. This means that whatever is in BYTE PTR SS:[EAX+ESP+10] will be moved into CL.
For argument1 we have CL. This is a new piece of assembly that hasn't been introduced in any of the previous tutorials. So let's go through what this CL is. Warning: it will be a long journey to get there!
Recall in the second tutorial that we learned about the EBP register (which stands for the extended base pointer). The EBP register held data for the program to utilize. We can see what the register is holding by looking at the registers pane in the top right of Ollydbg.
You might also notice in that same pane a few other words that begin with the letter E. That's because there are multiple registers a program can use. You know about the EBP already. Let's name the other ones:
EAX
ECX
EDX
EDX
ESP
ESI
EDI
EBP
EBX
Each of these registers are used to hold data or some type of data throughout the programs lifespan. We won't go into detail for all of them because that will be to hard to remember for now. But what we do need to cover is that some registers can segment themselves into smaller pieces.
Each register is 32 bits in length, and we access the entire register via its full name e.g: EAX. However, if we wanted to access just 16 bits of EAX we use AX. And if we wanted to access 8 bits of the AX we use AL or AH. This can be seen in the naming; EAX means extended accumulator register, AX means accumulator register, AH means accumulator high, and AL stands for accumulator low.
Example:
MOV EAX, 0FCA1240 - moves 0x0FCA1240 into the register
MOV AX, 6F4A - moves 6F4A into the AX register
MOV AH, 6F - moves 0x6F into the upper 8 bits of the AX register
MOV AL, 3 - moves 0x3 into the lower 8 bits of the AX register
OK. Let's bring it all together now. We have a value being moved into CL. The CL is counter lower register. Its the subset of the CX register who is the subset of the ECX register. So we are moving 8 bits of something into this register.
Notice in the picture below we have 6F in the ECX register. 6F also fills the space for CL. Notice that CH is 00, CX is 006F, and the entire ECX register is 0000006F.
6F is in CL |
NOTE: For argument2 its highly likely that your memory address and value that you will be seeing will be different. You should be able to follow the steps along easily and replace the values I have here with the ones on your computer.
Now lets go over argument2. This is what is being pushed into the CL register. The argument reads: BYTE PTR SS:[EAX+ESP+10] Although there is a lot of stuff in it, it is very easy to break down. By seeing the SS: we know it is referencing the stack segment. This means our eyes want to be on the stack frame panel in the lower right section of Ollydbg.
The Stack aka SS: |
The BYTE PTR tells us that we will be pulling a byte sized value off of the stack. What is inside the brackets tells us where on the stack we will be pulling the byte sized value. Inside the brackets we have EAX+ESP+10. If we add that up, it will give us the address of where to remove the value from. So let's do the simple math real quick. Looking at your registers pane (see above image), add the values in the corresponding registers:
EAX at the moment this program is running is 0.
ESP at the moment this program is running is 00BFF730.
And 10 is 10.
So load up your windows calculator and set it to programmer view.
EAX+ESP+10 |
BFF740 is equal to 36373839 |
If we step-over, we see CL is now 39. |
This concludes the explanation for the MOV CL, BYTE PTR:SS[EAX+ESP+10]. We can verify that it moves the value 39 into CL by stepping-over onto the next line and viewing the ECX register. The above picture shows this. Notice Ollybdg is now on the line after MOV CL, BYTE PTR:SS[EAX+ESP+10]. This means the previous line has been computed.
Now that was a lot of information. I hope this isn't overwhelming you! For the rest of the lines inside the loop I am not going to write a detailed explanation for those. I will do so on the next approach. Instead what I am going to write is how they work.
So what happens next in the loop is very simple. We are going to compare the value that was found and placed into CL versus another value on the stack (EAX+ESP+210). If these values match, then we are going to increment a counter (the counter is EAX) and remove another byte value from the stack and push it into CL. We won't be removing the same exact value from the stack but rather the number to the left of the one we had just used (the 39). We are going to repeat this until either the comparison fails, or the counter reaches the value of EDI.
If the comparison fails (CL does not match the value) then we are going to JUMP to the badboy message. This means the JNE SHORT inside the loop will be activated. Recall JNE means jump if NOT equal.
If the loop completes, the program will automatically run the path of showing the goodboy message.
From this information we can find an exploitable flaw. That is, as long as the JNE SHORT is never called then the program will always display the goodboy message. This is good information. This explains why the program gives the goodboy message when we placed a NOP in place of the JNE SHORT.
OK. I am going to cut the tutorial here and place the next approach in the upcoming tutorial. I really wanted to place it here, but I feel this is so much information for one to manage. On top of that this tutorial is already very lengthy. I do need to consider that you guys have other things to do =)
So in the next tutorial I will write about how to uncover the password, so that we do not have to patch the program. If you want some homework, then see if you can discover the password mechanism on your own, and enter an explanation in the comments below. Remember, the password mechanism is the loop itself.