Today we are going to be talking about how to solve the reverse_me of Sharif CTF .Well , to begin with, I would like to give special thanks to whoever contributed to the CTF for their time devoted in creating such great tasks .
So, let's start with most common step which a reverse engineer is accustomed to begging with :
Let's scan it with peid :
As one can see , the binary is packed with Aspack 2.12 .
Before proceeding , we load the executable into olly , and the first instruction we are going to see is 'pushad' , just step over it (f8) , then follow ESP in dump and make a hardware breakpoint on the first 4 bytes :
Then run it (F9) and you will see the following :
Well , simply put , the packer obviously uses the PUSH followed by the RETN instruction to land at the OEP which is at adress 004016BB .
Once you are there , you would notice some obfuscated code that was deliberatley obfuscated by the packer in order to fool the cracker , that's where the plugin 'Analyze This!' comes handy .
It's purpose is to convert raw data into assembly instructions , so right click and and click on 'Analyze This!' :
Now ,we have comprehensible machine instructions ,let's use "Dump debugged process" plugin which it's sole intention is to dump active debuggee process , so the very first thing you are going to need is to copy the value in 'modify' section into the clipboard and then click 'Dump' and save it as 'ReverseMe2'
Inevitably ,since the binary is packed, then it comes as no surprise that the IAT table is destroyed ,so in order to circumvent this ,we have to rebuild the IAT with 'IMPrec tool' .
so , run ' IMPrec" and then select the process of "ReverseMe" from the running process list and past the value that we have copied previously into the 'OEP' of IMPrec and click on 'IAT AutoSearch' and then on'Get Imports ', finally click on 'Fix dump' and select the executable "ReversMe2.exe" and it will be saved as "ReversMe2_.exe"
The important thing is that during these steps you have to be very careful ,otherwise the entire thing does not work .
After unpacking the binary ,now we are ready to reverse engineer it ,so load the "ReverseMe2_.exe"into olly and select "search for ->all intermodular calls"
then right click on "getdigitemtextA" API and click on "set breakpoint on every call to
getdigitemtextA" and run the program (F9) :
here , just put an email address and serial number and click on "OK",and you will hit the breakpoint on the first "getdigItextitem" api just step over them .
LEA EAX,DWORD PTR SS:[EBP-340] ; loads eax with memory address of the email
PUSH r_.0040FD0C ;push the memory address of '@' charchter
PUSH EAX ;push memory address of the email
CALL r_.004013A0 ; this routine checks to see whether email string contains '@'or not ,
ADD ESP,8 ; removes the addresses of email and '@' from the stack
TEST EAX,EAX ; checks the return value of the previous routine
JE SHORT r_.00401144 ; jumps if eax contains 0
LEA EAX,DWORD PTR SS:[EBP-340] ; loads eax with memory address of the email
PUSH r_.0040FD34 ; push the memory address of '.' charchter
PUSH EAX ; push memory address of the email
CALL r_.004013A0 ; this routine checks to see whether '@blabla.tn 'string contains '.'or not
ADD ESP,8 ;removes the addresses of '@blabla.tn 'string and '.' from the stack
TEST EAX,EAX ; checks the return value of the previous routine
JE SHORT r_.00401144 ;jumps if eax contains 0
LEA EAX,DWORD PTR SS:[EBP-340];loads eax with memory address of the email
PUSH r_.0040FD34 ;push the memory address of '.' charchter
PUSH EAX ;push memory address of the email
CALL r_.004013A0 ; the same routine previously called
ADD ESP,8 ;removes the addresses of '@blabla.tn 'string and '.' from the stack
CMP BYTE PTR DS:[EAX+1],0;compares the first char after the '.' with 0
JE SHORT r_.00401144 ;jumps if nothing after the point charachter
LEA EAX,DWORD PTR SS:[EBP-340] ; loads eax with memory address of the email
PUSH r_.0040FD0C; push the memory address of '@' charchter
PUSH EAX ;push memory address of the email
CALL r_.004013A0 ; this routine checks to see whether email string contains '@'or not
ADD ESP,8
CMP BYTE PTR DS:[EAX+1],2E ; compares the char after '@' with the '.'char
JNZ SHORT r_.0040114E ; else jump to serial checking routine
PUSH r_.0040FD10 ; ASCII "Your E-mail address in not valid."
JMP r_.004012A5 ; jump to nag
MOVQ MM0,QWORD PTR DS:[40FD70] ; loads MM0 with adress of "registration fail"
LEA ECX,DWORD PTR SS:[EBP-240] : loads ECX with the our serial
MOV AL,BYTE PTR DS:[ECX] ; moves the byte which ecx is pointing to , to AL
INC ECX ; r_.0040FD0D increments the address that ECX contains
TEST AL,AL ; checks whether AL contains 0 or not
JNZ SHORT r_.00401192 ; if not jump back and increment ECX
SUB ECX,EDX ; subtract ecx from edx
CMP ECX,10 ;checks the length of the serial
JNZ r_.004012A1 jump to nag if the length is not 16
CMP BYTE PTR SS:[EBP-240],42 ; compare the first char with 'B'
JNZ r_.004012A1 : if not equal jump to nag
MOVSX EAX,BYTE PTR SS:[EBP-231] ; moves the last char of the entered serial to EAX
ADD EAX,42 ; adds eax with 42
CMP EAX,9B ; and cmp it with 9b ,so the last char should be 9B - 42 = 59 which is 'Y'
JNZ r_.004012A1 else jump to nag
MOVSX ECX,BYTE PTR SS:[EBP-23F] ; it loads the second char
LEA EAX,DWORD PTR DS:[ECX-3] ; loads eax with ord(second char) - 3
CMP EAX,57 ;cmp it 57 ,that means the second char should be 57 + 3 = 5A which is 'Z'
JNZ r_.004012A1 else jump to nag
MOVSX EAX,BYTE PTR SS:[EBP-232] ; loads the 15h to eax char
ADD EAX,ECX ; adds eax with 5A
CMP EAX,9B ; the 15 element should be 9b - 5A = 41 the char is 'A'
JNZ r_.004012A1 else jump to nag
MOVSX ECX,BYTE PTR SS:[EBP-23E] ; load the 3rd char
LEA EAX,DWORD PTR DS:[ECX+1] ; ord(3rd char)+1
CMP EAX,3A ; 3 rd char is 39 = '9'
JNZ r_.004012A1 else jump
MOVSX EAX,BYTE PTR SS:[EBP-233] load the 14th char
ADD EAX,ECX ;
CMP EAX,9B ; the 14th char is 62h = 'b'
JNZ r_.004012A1 else jump to nag
CMP BYTE PTR SS:[EBP-23D],64 ; the 4th char is 'd'
JNZ r_.004012A1 else jump
MOVSX EAX,BYTE PTR SS:[EBP-234] ; loads the 13 char
ADD EAX,64
CMP EAX,9B ; the 13 th char is 37h = '7'
JNZ SHORT r_.004012A1 else jump to nag
CMP BYTE PTR SS:[EBP-23C],6D ; the 5th char is 'm'
JNZ SHORT r_.004012A1 else jump to nag
MOVSX EAX,BYTE PTR SS:[EBP-235] ; loads eax with 12th char
ADD EAX,81
CMP EAX,0C8 ; 12th char is c8 - 81 = 47h ..'G'
JNZ SHORT r_.004012A1 ; nag
MOVSX ECX,BYTE PTR SS:[EBP-23B] ; loads the 6th char
LEA EAX,DWORD PTR DS:[ECX-2D] ;
CMP EAX,44 ; the 6th char should be 44 + 2d = 71 = 'q'
JNZ SHORT r_.004012A1 else jump nag
MOVSX EAX,BYTE PTR SS:[EBP-236] ; the 11th char
ADD EAX,ECX ; r_.0040FD0D
CMP EAX,0AA ;the 11char is AA - 71 = 39h = '9'
JNZ SHORT r_.004012A1 ; nag
CMP BYTE PTR SS:[EBP-23A],34 ; the 7th char is '4'
JNZ SHORT r_.004012A1 ;nag
MOVSX EAX,BYTE PTR SS:[EBP-237] ; loads the 10th char
ADD EAX,34
CMP EAX,9B ; 10th char is 9b - 34 = 67h = 'g'
JNZ SHORT r_.004012A1 ;nag
CMP BYTE PTR SS:[EBP-239],63 ;the 8th char is 'c'
JNZ SHORT r_.004012A1 ;nag
MOVSX EAX,BYTE PTR SS:[EBP-238] ; the
ADD EAX,63
CMP EAX,9B ; the 9th char is 9b - 63 = 38h = '8'
JE SHORT r_.004012BB ; get past the nag screen
Well , after putting the chararcters in order ,the serial should be like this
= 'BZ9dmq4c8g9G7bAY'
That's it basically , the reverseme is very simple , the serial checking routine ain't that complicated , it is something that is learnt with time as you practice with machine instructions .
So I am expecting your valuable feedback and suggestions for betterment .