crackmes.one

Writeup for Find the pass

Author: lfanew
Date: 2021-05-10 05:39
Summary: Program takes a string from user, hashes value and compares to the expected hash at 00405064 - "pcx|xpzlhgu}" Two things stood out to me in this challenge. #1 - The compiler optimization for division. 004014b1 ba67666666 mov edx, 0x66666667 004014b6 89c8 mov eax, ecx 004014b8 f7ea imul edx 004014ba c1fa02 sar edx, 0x2 The above code is equivalent to simply dividing edx by 10, or (edx / 10). The reason for this has to do with a compilers affinity for working in powers of 2's and the cost of the division instruction. A good read on this can be found at: http://blog.dkbza.org/2007/09/reverse-engineering-compiler-produced.html A good reference on these operations can be found at: https://flaviojslab.blogspot.com/2008/02/integer-division.html #2 - Using an unnecessarily large buffer 00401472 8b4508 mov eax, dword [ebp+0x8 {pass}] 00401475 890424 mov dword [esp {var_6c_1}], eax 00401478 e88b270000 call strlen 0040147d 8945ec mov dword [ebp-0x14 {var_18}], eax 00401480 8b45ec mov eax, dword [ebp-0x14 {var_18}] 00401483 c1e002 shl eax, 0x2 00401486 890424 mov dword [esp {var_6c_2}], eax 00401489 e8da270000 call malloc // make the hashed password buffer 4x bigger The above code shows that the program gets the length of the password. We then allocate memory to that length shifted left 2 times. At first I wasn't sure of the purpose of why the developer did this until the end of the hashing function. 0040149a mov eax, dword [ebp-0xc {i}] 0040149d lea edx, [eax*4] // store i * 4, aka i shifted left by 0x2 004014a4 mov eax, dword [ebp-0x18 {offsets}] 004014a7 lea ebx, [edx+eax] // ebx now holds offsets[i*4] 004014aa call rand 004014af mov ecx, eax 004014b1 mov edx, 0x66666667 004014b6 mov eax, ecx 004014b8 imul edx 004014ba sar edx, 0x2 004014bd mov eax, ecx 004014bf sar eax, 0x1f 004014c2 sub edx, eax 004014c4 mov eax, edx 004014c6 shl eax, 0x2 004014c9 add eax, edx 004014cb add eax, eax 004014cd sub ecx, eax 004014cf mov edx, ecx 004014d1 mov dword [ebx], edx // store the current offset at offsets[i*4] 004014d3 add dword [ebp-0xc {i}], 0x1 I believe the reason for this is just throw a bit of confusion to the reverser. This way there will be 4 junk bytes between each hash offset in memory and will no longer be contiguous in memory. Conclusion: Other than those two things it just has a bit of math for the hashing function to get the offsets. I hope this read helps you :)

Loading writeup...