home *** CD-ROM | disk | FTP | other *** search
/ KeyGen Studio 2002 / KeyGen_Studio_2002.iso / Tutorials / CrackMesCbjNet / tragen_1_lightning.txt < prev    next >
Encoding:
Text File  |  2001-09-21  |  5.1 KB  |  167 lines

  1. -------------------------------------------------------------------------------
  2.  
  3. Tragen's Crackme #1
  4.  
  5. Another day, another crackme. After finding out that Tragen's #4 
  6. crackme uses a hash of the
  7. serial and the only way to crack it is a brute force, I decided to try 
  8. my hand at this
  9. crackme.
  10.  
  11. Upon running the app, we are presented with 5 boxes, a Check button, 
  12. and a Give Up button.
  13. I filled the boxes with 1234, 5678, 9012, 3456, and 7890. Being the app 
  14. uses MFC 4.2 to
  15. hide what it is doing, I had to use SoftIce and set a bpx on 
  16. GetDlgItemTextA. Clicking the
  17. Check button did not trigger the breakpoint though. I removed that 
  18. breakpoint and bpx'd on
  19. GetDlgItemA and proceeded to re-check the serial. This time I got a 
  20. hit. After fiddling
  21. around and getting back to our application's code, instead of in the 
  22. MFC42 dll, we can
  23. scroll upwards to find a range of NOPs. This is a signal that we are at 
  24. the top of the
  25. fuction, as all apps compiled with MFC 4.2 that I've found have been 
  26. this way. The address
  27. should be 00401560.
  28.  
  29. I prefer to do everything in W32Dasm so I proceeded to stop the app, 
  30. open up W32Dasm, and
  31. debug from there. Almost immediately after 00401560 are 5 calls to 
  32. MFC42.Ordinal:0C17. There
  33. are no pushes onto the stack that indicated a memory location to write 
  34. the data to though.
  35. After letting one of the functions execute, 0x04D2 was returned. After 
  36. looking at it for a
  37. few seconds, I realized that 1234 could be turned into hex and wondered 
  38. what it's hex
  39. counterpart was. The hex counterpart is 0x04D2. Now we know what that 
  40. Ordinal function is
  41. doing. Any values put in are turned from decimal into hex.
  42.  
  43. After the 5 calls, we run into a loop. Looking thru the references to 
  44. the stack, it can be
  45. noted that only the first byte in the values is referenced or used. It 
  46. appears, at least so
  47. far, that it is just wanting values between 0 and 255 as the other 
  48. bytes aren't being
  49. referenced. Below is a C version of the loop. Val1 and Val3 are the 
  50. values from the serial
  51. positions.
  52.  
  53. for(Counter1=1; Counter1 <= 0x0B09; Counter1++)
  54. {
  55.     Counter2++;
  56.     Counter3++;
  57.  
  58.     Key1 = Buffer3[Counter3] * Buffer2[Counter2];
  59.  
  60.     A = Buffer1[Counter1] * Val1;
  61.     A = ((A * Val1) ^ A) + Val3;
  62.     Key1 = Key1 ^ A;
  63.  
  64.     Counter5++;
  65.     Key1 = Key1 ^ (Buffer4[Counter5] * Buffer4[Counter4+1] * Val1);
  66.     Key1 = Key1 ^ (Buffer4[Counter4+1] + Val1) ^ Val1;
  67.  
  68.     Counter4++;
  69.  
  70.     if(Counter2 == 0x36)
  71.         Counter2 = 0;
  72.  
  73.     if(Counter3 == 0xD8)
  74.         Counter3 = 0;
  75.  
  76.     if(Counter4 == 5)
  77.         Counter4 = 0;
  78.  
  79.     if(Counter5 == 10)
  80.         Counter5 = 0;
  81. }
  82.  
  83. Note, Key1 is always overwritten the next time it goes thru the loop. 
  84. This means that the
  85. following code works just as well.
  86.  
  87. A = 0x00 * Val1;
  88. A = ((A * Val1) ^ A) + Val3;
  89. Key1 = 0x87 ^ A ^ (0x00 * 0x00 * Val1) ^ (0x00 + Val1) ^ Val1;
  90.  
  91. Of course, anything multiplied by 0x00 is 0. Anything xor'd against 
  92. itself is 0x00,
  93. therefore the xor is not undone. If you do a little bit of math on the 
  94. above function, you
  95. come up with the following.
  96.  
  97. Key1 = 0x87 ^ Val3;
  98.  
  99. Sure is a large loop for such an easy Key1 value. After the loop, Val1 
  100. is set to Key1. OK.
  101. Maybe this was just a screwup somewhere due to the buffers. either way, 
  102. This makes our life
  103. ALOT easier in figuring out Key1. Now to go on to the 2nd loop that is 
  104. after this one. The
  105. next loop does the exact same thing as the above loop does except Val1 
  106. is now Val2 and Val3
  107. is now Val4. This means that Val2 = 0x87 ^ Val4. That was easy. The 
  108. loop after this is the
  109. same as the 2nd loop except Val3 is used instead of Val2. So Val3 = 
  110. 0x87 ^ Val4. Val3 is
  111. not changed in memory on the 3rd loop but kept in a register.
  112.  
  113. Now I am going to scratch my head and wonder why no one else has turned 
  114. in a tutorial on
  115. this crackme. We are almost done. After those 3 terrible loops, we have 
  116. 2 calls then some
  117. checks we have to pass.
  118.  
  119. The function being called has 2 values passed to it. The function does 
  120. the exact same thing
  121. as the above loop except that you pass in the values you want to 
  122. manipulate. The first time
  123. thru, it does it with the 4th and 5th parts of the key. The 2nd time 
  124. thru, it does it with
  125. the new Key1 and the original Val5. This means that the following is 
  126. done.
  127.  
  128. Val1 = Val3 ^ 0x87;
  129. Val2 = Val4 ^ 0x87;
  130.  
  131. Now, the following must be true.
  132.  
  133. Val1 = 0x6C
  134. Val2 = 0xF4
  135. Val4 ^ 0x87 = 0xF4
  136. Val5 ^ 0x87 = 0xFA
  137. Val3 ^ 0x87 ^ 0x87 = 0xEB
  138.  
  139. Val1 must be 0x6C. Val1 is set to Val3 ^ 0x87. We have to find Val3 
  140. then.
  141. 0x87 ^ 0x6C = 0xEB so Val3 is 235. This can be confirmed as Val3 ^ 0x87 
  142. ^ 0x87 = 0xEB.
  143. 0x87 ^ 0x87 cancel each other so Val3 = 0xEB
  144.  
  145. Val2 needs to be 0xF4 and it is set to Val4 ^ 0x87. So 0x87 ^ 0xF4 = 
  146. 0x73. so Val4 is 115
  147. in decimal. This can be confirmed as Val4 ^ 0x87 must be 0xF4. 0x73 ^ 
  148. 0x87 = 0xF4
  149.  
  150. Val5 ^ 0x87 must be 0xFA. 0xFA ^ 0x87 = 0x7D or 125 in decimal.
  151.  
  152. Val1 and Val2 are never checked and are actually lost during the math. 
  153. This means any valid
  154. serial has anything for the first 2 numbers then Val3, Val4, and Val5 
  155. set correctly. Below
  156. is a working serial
  157.  
  158. 0 0 235 115 125
  159.  
  160. This crackme did not need any brute forcing and was very easy. The only 
  161. thing that would
  162. throw people is that it uses the MFC 4.2 stuff AND it uses loops that 
  163. are not needed. I'd
  164. give this a difficulty of 2 or 3.
  165.  
  166. Lightning
  167.