For this year’s birthday the most awesome gift I received was from hasherazade 🙂
I am very thankful to her for making my birthday so special 🙂
This crackme is a bootloader written in 16-bit assembly. This is how this look like.
After attaching the process to IDA I placed a breakpoint in the user input and this is the algorithm which calculates the password.
sub_7C5C proc near
push si
xor ax, ax
mov word_7DCB, ax
loc_7C62:
test cx, cx
jz loc_7C72
xor byte ptr word_7DCB+1, ah
lodsw
dec cx
add word_7DCB, ax
jmp short loc_7C62
loc_7C72:
pop si
retn
sub_7C5C endp
After calculating, the result is compared with 0x39A.
There can be lots of possible collisions in this algorithm. I used a dictionary file to find all possible combinations of 0x39a. This is the cpp code using inline assembly.
#include "stdafx.h" | |
#include <string> | |
#include <iostream> | |
#include <fstream> | |
/* | |
* Author : Osanda Malith Jayathissa (@OsandaMalith) | |
*/ | |
using namespace std; | |
int valid( char *str) { | |
char String[100]; | |
strcpy_s(String, str); | |
unsigned int var; | |
_asm { | |
lea esi, [String] | |
xor eax, eax | |
mov[var], eax | |
mov ebx, 0 | |
mov ecx, 4 | |
_loop: | |
test ecx, ecx | |
jz _finish | |
xor byte ptr[var + 1], ah | |
lodsw | |
dec ecx | |
add[var], eax | |
jmp _loop | |
_finish : | |
} | |
return var; | |
} | |
int main(int argc, char const *argv[]) { | |
string line; | |
ifstream myfile("my1.txt"); | |
if (myfile.is_open()) | |
{ | |
while (getline(myfile, line)) | |
if (valid((char *)line.c_str()) == 0x39a) | |
cout << line.c_str() << endl; | |
myfile.close(); | |
} | |
else cout << "Unable to open file"; | |
return 0; | |
} |
This is cpp version where I’ve written the algorithm in cpp.
#include "stdafx.h" | |
#include <string> | |
#include <iostream> | |
#include <fstream> | |
using namespace std; | |
unsigned int checksum(unsigned char string[]) { | |
unsigned int var; | |
unsigned int eax; | |
unsigned int ecx; | |
unsigned int esi; | |
unsigned char value1; | |
unsigned char value2; | |
unsigned char value3; | |
unsigned int * pointer1; | |
unsigned int * pointer2; | |
unsigned int * pointer3; | |
int a; | |
/* pointer1 should point to the second byte of var */ | |
pointer1 = &var; | |
a = (int)pointer1; | |
a = a + 1; | |
pointer1 = (unsigned int *)a; | |
/* pointer2 should point to the first byte of eax */ | |
pointer2 = &eax; | |
/* pointer3 should point to the second byte of eax */ | |
pointer3 = &eax; | |
a = (int)pointer3; | |
a = a + 1; | |
pointer3 = (unsigned int *)a; | |
esi = 0; | |
eax = 0; | |
var = 0; | |
ecx = 4; | |
while (ecx != 0) | |
{ | |
/* xor byte ptr [var+1], ah */ | |
value1 = eax >> 8; | |
value2 = var >> 8; | |
value3 = value1 ^ value2; | |
*pointer1 = value3; | |
/* lodsw */ | |
* pointer2 = string[esi]; | |
*pointer3 = string[esi + 1]; | |
esi = esi + 2; | |
/* dec ecx */ | |
ecx–; | |
/* add [var], eax */ | |
var = var + eax; | |
} | |
return var; | |
} | |
int _tmain(int argc, _TCHAR* argv[]) | |
{ | |
string line; | |
ifstream myfile("my1.txt"); | |
if (myfile.is_open()) | |
{ | |
while (getline(myfile, line)) { | |
unsigned int var = checksum((unsigned char *) line.c_str()); | |
if (var == 0x39a) | |
cout << line.c_str() << endl; | |
} | |
myfile.close(); | |
} | |
else cout << "Unable to open file"; | |
return 0; | |
} |
The results: http://pastebin.com/9rMwwVgq
Any of these passwords work 🙂 but the correct password to unlock the source code in the link is “awesome” 🙂
Once again Thank You so much! <3
One thought on “Birthday Crackme Part 1”