How they protect YOUR data
It is a damn good feeling, I tell ya, to know that there are Fravias like Latigo around: a nightmare for all lazy and incompetent programmers... eheh
"I started trying to reverse other proggie's security... maybe future essays?" Yes Latigo! Go ahead!
This is not a tutorial on how to patch,crack,serial fish or keygen a program. This essay is about Calypso's (email client) security. Whenever you try open your password protected .box mail file a dialog box will pop up asking for a user and pass.I tested it security and ended up making a 'Calypso 3.00 password recovery tool' :). (Click here to get it asm source included)
Calypso is a nice email program.Everything from accounts passwords,program settings and even emails are kept in ONE file;that makes it very easy when you are moving from one pc to another one or when you want to backup your mail.Of course, this presents some major risk as you might have already wondered.
This file (which has a .box extension) is,in some way,'crypted' for obvious reasons.So i wanted to give it a try...i wanted to see how good this 'encryption' was, and thats how i started the password protection reverse engineering.
When you double click on a .box file, you will get the typical dialogbox waiting for a password. At this point, the 'encrypted' password (which is stored in the .box file as you remember :D ) is decrypted in memory and it is compared to what we input once we click on the 'ok' button. But since we dont want to make a patch or to fish for the right pass, we should tackle the program BEFORE the dialogbox pops up (that is, before the password is decrypted). So lets bpx on CreateFileA, to intercept calypso when trying to open the .box file.
Of course, we will break on other calls to CreateFile before the one we want to. (at least once, since we double click on the file thus generating a call to CreateFile). Argh!! whats this? we break on shell32.dll so i do a F12 (p ret) to return from that call to CreateFile,and then i press F5 to exit from SoftIce and to break on another call...BOOM back in softice (hi Zito :D)..again shell32.dll so another F12 and another F5 and again and again till we end in calypso's code.
(IMPORTANT:Please, this is a tutorial for newbies, but that doesnt mean that i'll tell you EXACTLY how many F12's or F5's you must press.. -some- knowleadge is assumed ;)
Ok so finally we end up in calypso's code at 1000B886 in the MAILDB32 module..but whats this module? lets see ..i throw a MOD MAILDB32 and softice tells me that this is the maildb32.dll and which is in the same folder as calypso.exe..thus, we are in the right path.
Well, we have a CreateFile but we dont know which file this dll is trying to open...
LPCTSTR lpFileName, // pointer to name of the file
DWORD dwDesiredAccess, // access (read-write) mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // pointer to security attributes
DWORD dwCreationDistribution, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to file with attributes to copy
As you can see, the first argument to this api is the name of the file, that means, that in softice we have to look for the LAST argument pushed to the stack before the CreateFile api is called.
:1000B85E 6880000010 push 10000080 // handle to file with attributes to copy
:1000B863 8BC8 mov ecx, eax
:1000B865 6A03 push 00000003 // file attributes
:1000B867 6A00 push 00000000 // how to create
:1000B869 83E103 and ecx, 00000003
:1000B86C 6A00 push 00000000 // pointer to security attributes
:1000B86E 68000000C0 push C0000000 // share mode
:1000B873 52 push edx // pointer to name of the file <-----this one!
:1000B874 F3 repz
:1000B875 A4 movsb
:1000B876 896D10 mov dword ptr [ebp+10], ebp
:1000B879 C7451801000000 mov [ebp+18], 00000001
* Reference To: KERNEL32.CreateFileA, Ord:0031h
:1000B880 FF1524700110 Call dword ptr 
Now we know that we need to dump the EDX register to know which file this program is trying to open..but since the EDX register was modified when the CreateFileA api was called, we need to break BEFORE 1000B880 and then yes, dump EDX.
So i clear my breakpoints (bc *) and put a breakpoint on 1000B873.Double click again on the .box file and BOOOOOOOOOOOm back in Sice :). But this time ill do a 'D EDX' and guess what i got? yeah! the path to my latigo.box :) we are on the right path d00d3 :D.
Now we know that the file is opened,and the bitch must about to read it , so lets be ready for a ReadFile api! Keep on tracing till we find something interesting:
* Reference To: KERNEL32.ReadFile, Ord:01D6h
:1000B8F8 8B3D1C700110 mov edi, dword ptr [1001701C]
mmmmm the bitch is getting prepared....more tracing...ah! again:
* Reference To: KERNEL32.SetFilePointer, Ord:0219h
:1000B908 FF1518700110 Call dword ptr 
Calypso is going to read our beloved .box file anytime...and finally:
1000B959 FFD7 call edi
Remember that some time ago, calypso MOVed ReadFile into EDI? well, now its calling EDI, and that means that is calling ReadFile :).
HANDLE hFile, // handle of file to read
LPVOID lpBuffer, // address of buffer that receives data
DWORD nNumberOfBytesToRead, // number of bytes to read
LPDWORD lpNumberOfBytesRead,// address of number of bytes read
LPOVERLAPPED lpOverlapped // address of structure for data
1000B945 8D542410 lea edx, dword ptr [esp+10]
1000B949 6A00 push 00000000 // address of structure for data
1000B94B 52 push edx // address of number of bytes read
1000B94C 8D8520010000 lea eax, dword ptr [ebp+00000120]
1000B952 6824020000 push 00000224 // number of bytes to read
1000B957 50 push eax // address of buffer that receives data
1000B958 56 push esi // handle of file to read
1000B959 FFD7 call edi
Lets see..this maildb32.dll is about to read 0x224 bytes from latigo.box and is going to store that in the address pointed by EAX. Let the .dll read all the bytes it wants to and lets keep on tracing..hehe check this out:
1000B9A7 8D9D20010000 lea ebx, dword ptr [ebp+00000120]
1000B9AD 6824020000 push 00000224
1000B9B2 53 push ebx
Reference To: MAILDB32.mdbDecrypt
1000B9B3 E8C8460000 call 10010080
Decrypt?????? wtf! :D we are getting to the end!! i do a 'd ebx' and see the same thing that i'd see if i viewed the latigo.box file with a hex editor...that means that what has been read at 1000b959 , is being passed as a parameter to the mdbDecrypt function. Foolproof :D.
Fasten your seatbelts! here we come!
I step into the mdbDecrypt call (F8) and start tracing the code inside this badly named method:
Exported fn(): mdbEncrypt - Ord:0031h
10010040 55 push ebp
10010041 8BEC mov ebp, esp
10010043 F60518A0011004 test byte ptr [1001A018], 04
1001004A 7530 jne 1001007C
1001004C 57 push edi
1001004D 56 push esi
1001004E 50 push eax
1001004F 51 push ecx
10010050 56 push esi
10010051 57 push edi
10010052 8B4D0C mov ecx, dword ptr [ebp+0C]
10010055 C1E902 shr ecx, 02
10010058 8B7508 mov esi, dword ptr [ebp+08]
1001005B 8BFE mov edi, esi
1001005D FC cld
1001005E E316 jcxz 10010076
10010060 AD lodsd
10010061 F7D0 not eax
10010063 2C43 sub al, 43
10010065 80EC43 sub ah, 43
10010068 C1C010 rol eax, 10
1001006B 2C43 sub al, 43
1001006D 80EC43 sub ah, 43
10010070 C1C010 rol eax, 10
10010073 AB stosd
10010074 E2EA loop 10010060
10010076 5F pop edi
10010077 5E pop esi
10010078 59 pop ecx
10010079 58 pop eax
1001007A 5E pop esi
1001007B 5F pop edi
Referenced by a (U)nconditional or (C)onditional Jump at Address:
1001007C 5D pop ebp
1001007D C20800 ret 0008
Thats all the mdbDecrypt method...whatever it is, it cannot be too complicated :D.
Lets analyze it:
In 10010058 the program puts in ESI ,the same thing that can be found in EBX..that is, what has been read from the latigo.box file..and then it copies the contents of ESI to EDI..
At 10010060 is where fun starts:
10010060 LODSD <- This instruction 'Loads' 4 bytes from the ESI register into the EAX register.
10010061 not eax <- Inverts the bits of EAX forming the 1st complement.
10010063 sub al, 43 <- substracts 43h from AL
10010065 sub ah, 43 <- substracts 43h from AH
10010068 rol eax, 10 <- Rotate left the EAX register 10 times
1001006B sub al, 43 <- substracts 43h from AL
1001006D sub ah, 43 <- substracts 43h from AH
10010070 rol eax, 10 <- Rotate left the EAX register 10 times
10010073 stosd <- store in EDI the 4 bytes contained in EAX
10010074 loop 10010060 <--repeat whole process as many times as ECX indicates.
So basicaly what this does is take 4 bytes in EAX from ESI, do something to them and store them in EDI :D pretty simple.
This is more than enough to make a tool which decrypts the file, read the password and display it.Just copy and paste code! :D.
Later on , i discovered the position in the .box file where the password is kept and some other thingies, but i dont want to bother you.
You can find the program i made here, source included.
I hope you liked this tut and i also hope that it was not too long or boring :).
Greetings to all the nice people @ #cracking4newbies ,to Fravia+ (thanks) and special greetings to MAC and Zito of course :).
toolsanonymity academycocktailsantismut CGI-scriptsmail_Fravia
Is reverse engineering legal?