home *** CD-ROM | disk | FTP | other *** search
- . ..: Smart 5 by ajax - A tutorial by DEATH of Execution :.. .
- `------------------------------------------------------'
-
- Introduction
- -------------
- I made this tutor because I didn't see any other tutorial considering this
- crackme in Eternal Bliss's site (crackmes.cjb.net or surf.to/crackmes) .
- I have cracked this crackme long time ago, so I'll just recrack it.. :)
-
-
- Greetings
- ----------
- I'd like to greet Eternal for having such a wonderful crackme site ;)
-
-
- Tools
- ------
- - Notice I will use Turbo Debugger, that's because I am hearing MP3's right now
- and I don't want Soft-ICE to stop'em ;)
- - Ajax Smart 5 ;)
-
-
- Start
- ------
- Ok.. Load up the crackme in TD. First you see a jump.. Not interesting :)
- The jump brings us to an INT 3h which is the debugger's breakpoint interrupt..
- We'll just ignore it..
- Now the crackme prints the 'Enter password' string:
- mov dx, 103h ; that's the string to print
- mov ah, 9h ; PRINT STRING service
- int 21h ; do'em
-
- Now the crackme will ask for the password:
- mov dx, 131h ; Entered Password buffer
- mov ah, 0Ah ; GET STRING FROM KEYBOARD service
- int 21h ; get'em
-
- So.. in the memory view window, we GoTo ds:133h .. Why?
- String buffer structure is like this:
- Name Type Position
- --------------------------------------------------------
- Maximum_Characters db 0
- Character_Count db 1
- Buffer db Maximum_Characters 2
-
- Check out what's the Maximum_Characters.. It's 5 (+1 for Carriege Return).
- By the way, we see the buffer overwrites the code before the GET STRING code..
- Now the crackme will move the buffer position to bx:
- mov bx, 131h
-
- Now.. A call.. We trace into it, what do we see? 32-bit Registers! No panic..
- Just go to the Registers window, right mouse click on it, and choose 32-Bit
- Registers option (if it's not already turned on).
-
- Here's the procedure:
- mov eax, 0D12345h ; eax = 0D12345h (hardcoded)
- mov cx, 10h ; ecx = 64 times for loop
- loop1:
- xor ax, 2h ; eax gets xored by 2
- inc ax ; eax++
- cwde ; convert word to double word with eax
- loop loop1 ; till ecx = 0
- dec eax ; eax--
- ret ; return from call
-
- This just calculates another value for eax.. Seems that ajax wanted to confuse
- us thinking it's an important code instead of just putting a 'mov eax, 2354h'.
-
- Another call.. here's the procedure:
- mov cx, 0Ah ; ecx = 10 times for loop
- loop1:
- xor eax, ebx ; this xors eax (2354h) by ebx (131h)
- loop loop1 ; loop tha loop
- ret ; return from call
-
- Ok.. First, let me say that if you XOR a value twice by the same number, the
- value will be the same.. :)
- Since 10 is an even number, eax will stay 2354h.. Another routine to confuse
- us..
-
- Another call, this time it's an important call, that calculates the checksum
- for the password:
- mov cx, 0Ah ; ecx = 10 times for loop
- loop1:
- xor eax, ebx ; xors eax by ebx (131h)
- shr eax, 1 ; eax gets divided by 2
- loop loop1 ; loopah
- and eax, 2Ah ; eax (0E7h) ANDed with 2Ah
- sub eax, [bx] ; eax (22h) gets subtracted by double
- ; word of the first four bytes of
- ; the entered password buffer
- ; (which are the character_max,
- ; character count, and two
- ; first characters of password)
- sub eax, [bx + 1] ; eax gets subtracted by double
- ; word of the entered password buffer
- ; (which are the character count, and
- ; three first characters of password)
- sub eax, [bx + 2] ; eax gets subtracted by double
- ; word of the entered password buffer
- ; (which are the first four characters
- ; of the entered password)
- sub eax, [bx + 3] ; eax gets subtracted by double
- ; word of the entered password buffer
- ; (which are four characters of the
- ; entered password starting from the
- ; second character)
- sub eax, [bx + 4] ; eax gets subtracted by double
- ; word of the entered password buffer
- ; (which are three last characters of
- ; the entered password + carriege
- ; return byte (0Ah))
- sub eax, [bx + 5] ; eax gets subtracted by double
- ; word of the entered password buffer
- ; (which are last two characters of the
- ; entered password + carriege return
- ; byte (0Ah) + hardcoded byte '!')
- rol eax, 1 ; eax gets rotated left by 1
- inc eax ; eax++
- ret ; return from call
-
- Phew.. Read it until you get it..
-
- After the call, ax (lower word of eax) gets compared with an hardcoded value
- of 0B4E3h and if it's equal, then we have succeeded to crack it :)
-
- So how do we get a valid password? We have two options:
- 1> Reverse the checksum (might take a little brain-effort)
- 2> Brute (easier.. 5 characters + 16-bit checksum.. fast too)
-
- This time I have chosen the second option since I am having a little
- headache..
-
- Brute forcer code
- ------------------
- Ok.. here's my source of the bruteforcer, of course you could make it better
- and use it on other crackmes, but it's good for Smart 5.. It's good for us :)
-
- --cut here--
- ; Solve to ajax's Smart 5 crackme
- ; (c)1999 by DEATH of Execution
- ;
- ; Brute force attack
- ; -------------------
- ; This crackme needed only 5 printable characters and had a 16bit checksum
- ; value, so I realized it wouldn't take much long before I could crack it..
- ; Phun, eh?
- ;
- ; This will crack for printable chars.
- ;
- .model tiny
- .386p
- .code
- org 100h
- start:
- lea ebx, passbuf
-
- mov byte ptr ch1, ' ' - 1
-
- ch1loop:
- mov byte ptr ch2, ' ' - 1
- mov byte ptr ch3, ' ' - 1
- mov byte ptr ch4, ' ' - 1
- mov byte ptr ch5, ' ' - 1
-
- inc byte ptr ch1
- cmp byte ptr ch1, '~' + 1
- jae nofound
-
- ch2loop:
- mov al, '.'
- int 29h
-
- mov byte ptr ch3, ' ' - 1
- mov byte ptr ch4, ' ' - 1
- mov byte ptr ch5, ' ' - 1
-
- inc byte ptr ch2
- cmp byte ptr ch2, '~' + 1
- jae ch1loop
-
- ch3loop:
- mov byte ptr ch4, ' ' - 1
- mov byte ptr ch5, ' ' - 1
-
- inc byte ptr ch3
- cmp byte ptr ch3, '~' + 1
- jae ch2loop
-
- ch4loop:
- mov byte ptr ch5, ' ' - 1
-
- inc byte ptr ch4
- cmp byte ptr ch4, '~' + 1
- jae ch3loop
-
- ch5loop:
- inc byte ptr ch5
- cmp byte ptr ch5, '~' + 1
- jae ch4loop
-
- mov eax, 22h ; magic value
- sub eax, [ebx]
- sub eax, [ebx + 1]
- sub eax, [ebx + 2]
- sub eax, [ebx + 3]
- sub eax, [ebx + 4]
- sub eax, [ebx + 5]
- rol eax, 1
- inc eax
-
- cmp ax, 0B4E3h ; checksum value
- jne ch5loop
-
- mov byte ptr endtext, 0Ah
- mov ah, 9
- lea dx, ch1
- int 21h
- mov byte ptr endtext, '!'
- jmp ch5loop
-
- nofound:
- int 20h
-
-
- passbuf db 06h ; Maximum chars
- db 05h ; entered chars
- ch1 db ?
- ch2 db ?
- ch3 db ?
- ch4 db ?
- ch5 db ?
- endtext db '!' ; hardcoded
- db 0Dh
- db '$'
- end start
- --stop cutting here--
-
- I threw the output to file, and tried to 'fish' readable words of passwords..
- I have found a good password: 'Sorry' .. Tried it, it worked..
-
- Now go ahead and crack Smart 6.. Hope this tut was good :)
-
- - DEATH of Execution in 1999
- <ab4ds@hotmail.com>
-
-