The analyst's weird crackme.

protection: Buffer overflow.

date: 07/17/2001

 

Published by +Tsehp

 

 

Hello all, here comes my solution for my little crackme.

I didn't receive much answers, but i hope you will try it with this solution.

 

 

tools used :

 

- IDA mostly

- Soft ice

- hexeditor (optional)

 

1) study of the crackme

 

 

ok, i first ran it to see what appened:

 

 

-- The analyst's weird crackme --

---------------------------------

enter your serial please:

 

 

ok, alright, i enter a serial such as : IOWNU

once you press Enter, nothing happens.If we press again, it closes for good.

ok let's use IDA and disassemble our weird.exe.It takes a lil while and then we

see that :

 

 

CODE:00401108                 push    ebp

CODE:00401109                 mov     ebp, esp

CODE:0040110B                 add     esp, 0FFFFFFB4h ; char

CODE:0040110E                 push    offset aTheAnalystSWei ; __va_args

CODE:00401113                 call    _printf                           ; print some text.

CODE:00401118                 pop     ecx

CODE:00401119                 push    offset asc_40C097 ; __va_args

CODE:0040111E                 call    _printf                           ; same

CODE:00401123                 pop     ecx

CODE:00401124                 push    offset aEnterYourSeria ; __va_args

CODE:00401129                 call    _printf                           ; same again

CODE:0040112E                 pop     ecx

CODE:0040112F                 lea     eax, [ebp+s]                      ; buffer

CODE:00401132                 push    eax             ; s

CODE:00401133                 call    _gets                             ; get entered serial

CODE:00401138                 pop     ecx

CODE:00401139                 nop

CODE:0040113A                 lea     edx, [ebp+s]

CODE:0040113D                 push    edx             ; s

CODE:0040113E                 call    _strlen                           ; get his length

CODE:00401143                 pop     ecx

CODE:00401144                 mov     edx, eax

CODE:00401146                 cmp     edx, 19h                          ; is it less than 25?

CODE:00401149                 jl      short loc_401182                        ; yeah

CODE:0040114B                 cmp     edx, 78h                          ; is it more than 120?

CODE:0040114E                 jg      short loc_401182                        ; yeah

CODE:00401150                 mov     eax, 1                            ; eax = 1 , initialise loop

CODE:00401155                 cmp     edx, eax                          ; did all chars?

CODE:00401157                 jl      short loc_40115E                        ; no let's jump

CODE:00401159

CODE:00401159 loc_401159:                             ; CODE XREF: _main+54j

CODE:00401159                 inc     eax                         ; eax = eax + 1

CODE:0040115A                 cmp     edx, eax                          ; did all chars?

CODE:0040115C                 jge     short loc_401159                        ; no let's loop

CODE:0040115E

CODE:0040115E loc_40115E:                             ; CODE XREF: _main+4Fj

CODE:0040115E                 mov     eax, 7A69h                        ; eax = 31337

CODE:00401163                 test    eax, eax

CODE:00401165                 jnz     short loc_401182                        ; jump quit

CODE:00401167                 cmp     eax, 1388h

CODE:0040116C                 jl      short loc_401182                        ; jump quit

CODE:0040116E                 cmp     eax, 3A98h

CODE:00401173                 jg      short loc_401182                        ; jump quit

CODE:00401175                 jmp     short loc_401182                        ; jump quit

CODE:00401177 ; ---------------------------------------------------------------------------

CODE:00401177                 push    offset aWooCongrats ; __va_args         ; good boy message

CODE:0040117C                 call    _printf

CODE:00401181                 pop     ecx

CODE:00401182

CODE:00401182 loc_401182:                             ; CODE XREF: _main+41j

CODE:00401182                                         ; _main+46j ...

CODE:00401182                 call    _getch                            ; wait till a key is pressed

CODE:00401187                 xor     eax, eax

CODE:00401189                 mov     esp, ebp

CODE:0040118B                 pop     ebp

CODE:0040118C                 retn

 

 

A quick look show us that there is NO x-ref to our good boy message, but rather some jumps that go directly to the

end of the crackme.

Quite weird, isn't it ? oh isn't it the name of my crackme? :)

Let's have a look at the goal of that crackme to see what we have to do.

lemme past my 1st post on the message board:

 

 

"the goal is to enter a serial and to get the good boy message..

however , it is not as easy as it seems

i never seen such a crackme, and i wonder how would you guys

use your reversing skill to complete that one

NO PATCH allowed "

 

 

 

ok goal is to get the good boy message, without patching it:)

just enter a serial. interesting, but how can we do it, without patching when there is no jump to the good

boy message?

 

 

i see no way except a nice buffer overflow ;-)

wtf? this is pretty new, isn't it ? in crackme at least.

ok, first, what is a buffer overflow ?

 

A buffer overflow happens when the string that we enter is bigger than our buffer.

so it overflows. the values that are over the buffer might get executed.

If we put some random values, the program crashes, but if we put good ones then the code is executed!

Once you have read that tutorial, i advise you to get your hand on some nice tutorials, such as 'smashing the stack',

and other nice ones in phrack magazine.

Phrack 55 has a nice tutorial about Win32 buffer overflow, that i advise you to read.

ok let's continue now.

 

2)overflowing the beast

 

 

ok, First of all, we have to check if there is a buffer and its size.

 

 

 

CODE:0040112E                 pop     ecx

CODE:0040112F                 lea     eax, [ebp+s]                      ; buffer

CODE:00401132                 push    eax             ; s

CODE:00401133                 call    _gets                             ; get entered serial

CODE:00401138                 pop     ecx

CODE:00401139                 nop

CODE:0040113A                 lea     edx, [ebp+s]

CODE:0040113D                 push    edx             ; s

 

 

ok, this is obvious.eax is pushed on the stack, just before a call to the 'gets' function.

lemme put some C code to demonstrate it :)

 

--------------------------------------------------------------------------------

 

#include <stdio.h>

#include <string.h>

#include <conio.h>

#include <iostream.h>

 

int main(){

 

    unsigned char name[50];

 

    gets(name);

 

--------------------------------------------------------------------------------

 

As we can see, there is a buffer called 'name' which is 50 bytes long.

then, we use 'gets'. our input goes into 'name'.

We defined it as 50 chars long. but what happen if we type 100 chars in ? a nice overflow ;)

I hope you are folloing me.

 

 

let's continue.

We have to check how big is our buffer.According to IDA it is 75 chars long.

 

First, we look our stack parameters:

 

CODE:00401108 s               = byte ptr -4Ch

CODE:00401108 argc            = dword ptr  8

CODE:00401108 argv            = dword ptr  0Ch

CODE:00401108 envp            = dword ptr  10h

CODE:00401108 arg_11          = dword ptr  19h

 

see 's' ?

run softice and do :

? ~-4C

it gives us 75 :o)

 

For me it looks pretty much that the max size of the buffer is 75 chars.

Let's test and enter something like 80 chars :

 

-- The analyst's weird crackme --

---------------------------------

enter your serial please:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

 

 

our program crashes nicely , no wonder ;-)

we entered a string of 80 chars, which is 4 chars more than the max size of the buffer.

Having a look at the registers, i can see that EBP=41414141.

Interesting isn't it ? where are those 41h coming from ?

41h is the hexadecimal ascii value of "A" ;))

so we just overwrote EBP.. ok nice, but the best thing would be to overwrite EIP ;))

Once EIP is overwritten, we can execute any code we want!

ok, lets enter 84 chars to see what happens now :

 

 

 

-- The analyst's weird crackme --

---------------------------------

enter your serial please:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

 

ok now our app still crash, but we get :

instruction at the address 41414141h uses the memory address at 41414141h. memory cannot be read.

it in fact , tries to execute code at VA : 41414141h.

ok now i *HOPE* you know what to do !

 

what about replacing our return address with something different than 41414141h ?

say, something like the good boy message location ?

 

CODE:00401177                 push    offset aWooCongrats ; __va_args  ; good boy

CODE:0040117C                 call    _printf

 

 

hmm, ok we have to put '401177' as our return address and it will obvisously print it on our screen :)

ok, just before to do that, let's try to enter a different serial such as :

 

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1234

 

why ? just to see what is the return address now.we might have to reverse the byte's order.

 

 

here we go, it crashes at address "34333231h". so we have to inverse our return address.

now we have : 771140. this is "w@" in ascii

 

let's try to enter it :

 

C:\attente>weird

-- The analyst's weird crackme --

---------------------------------

enter your serial please:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAw^Q@

 

wOO! congrats ;)

 

 

 

WOO! it worked!

note: there is still the pause that wait till we press a key, but when we press that key, EIP

get executed and we land at the good boy message!

 

here we go. :)

as i said, it was not that difficult, but rather new for a crackme ;)

i hope you learnt something from it, and i advise you to read some essays from phrack magazine.

Such as "Smashing the stack", and the one on win32 buffer overflow (phrack 55).

 

 

3) source of my lame weird crackme ;) (coded in 15 secondes)

 

 

#include <stdio.h>

#include <string.h>

#include <conio.h>

#include <iostream.h>

 

int main(){

    int i,len,temp;

 

    unsigned char name[75];

 

 

 

 

 

    unsigned long check=0;

 

    printf("-- The analyst's weird crackme --\n");

    printf("---------------------------------\n");

    printf("enter your serial please:\n");

 

    gets(name);

    asm{ nop};

 

    len=strlen(name);

   

    //cout << len;

    if (len < 25) goto theend;

    if (len > 120 ) goto theend;

    for (i=1; i <= len ; i++)

    {

       temp += name[i] ;   

     }

   

    if (temp = 31337) goto theend;

    if (temp < 5000) goto theend;

    if (temp > 15000) goto theend;

   

    goto theend;

 

          printf("wOO! congrats ;)\n");         

 

    theend:

   

    getch();

    return 0;

}

 

 

greetings go to :

 

duelist,dimedrol,ivanopulo,nu,CrackZ,G-Rom,iceman,theowl,spath,frog's print,Warezpup,corn,tin,

llama,quantico,carpathia,pain, yoshi,corn,amante.

i just can't be arsed to type every goddamn nicks, so greetings to my pal in #cracking4newbies, #ol,#ukc.

 

 

copyright pissed away, all right reversed

 

 tHE ANALYST [ID/UCF/HERT]

 

www.oldFravia.cjb.net

www.immortaldescendants.org