20/06/2010

Write up ndh crackme level 3

Ici on a à faire a un anti-debugger, en regardant GetModuleH dans les références de notre module actuel, on tombe sur :

00401060   > 68 0C934000    PUSH cm3.0040930C                  ; /ProcNameOrOrdinal = "IsDebuggerPresent"
00401065   . 68 20934000    PUSH cm3.00409320                        ; |/pModule = "Kernel32.dll"
0040106A   . FF15 6C804000  CALL DWORD PTR DS:[<&KERNEL32.GetModuleH>; |\GetModuleHandleA
00401070   . 50             PUSH EAX                                 ; |hModule
00401071   . FF15 74804000  CALL DWORD PTR DS:[<&KERNEL32.GetProcAdd>; \GetProcAddress
00401077   . FFD0           CALL EAX
00401079   . 33DB           XOR EBX,EBX
0040107B   . 85C0           TEST EAX,EAX
0040107D   . 74 07          JE SHORT cm3.00401086

On patch le saut conditionnel JE -> JMP et hop ça marche on peut lancer notre exécutable tranquillement. On suit le thread qui vient d'être cré et on va venir chercher notre fameuse référence GetWindowTextA :

00401570   . FF15 58814000  CALL DWORD PTR DS:[<&USER32.GetWindowTextA>]        ; \GetWindowTextA

Ça devient pareil ces challenges on regarde plus bas :

004015AF   . 83F8 10        CMP EAX,10
004015B2   . 0F85 7A000000  JNZ cm3.00401632

Donc ici notre password devra être d'une longueur de 16 ( 0x10 ) caractères. Prenons le password suivant comme point de départ : "abcdefghijklmnop". Plus loin on voit l'appel à une routine :

004015BD   . FF15 B0C64000  CALL DWORD PTR DS:[40C6B0]

Si on va voir ce qui se passe dedans on peut voir plusieurs sauts conditonnels vers 003800D5 qui fera échouer l'authentification. Restons sur notre exemple "abcdefghijklmno" :

00380011   8A42 03          MOV AL,BYTE PTR DS:[EDX+3]  << 'd'
00380014   8A22             MOV AH,BYTE PTR DS:[EDX]  << 'a'
00380016   3AC4             CMP AL,AH  << 'd' == 'a'
00380018   0F85 B7000000    JNZ 003800D5
0038001E   8A42 01          MOV AL,BYTE PTR DS:[EDX+1]  << 'b'
00380021   8A62 08          MOV AH,BYTE PTR DS:[EDX+8]  << 'i'
00380024   3AC4             CMP AL,AH  << 'b' == 'i'
00380026   0F85 A9000000    JNZ 003800D5
0038002C   8A42 05          MOV AL,BYTE PTR DS:[EDX+5]   << 'f'
0038002F   3C 72            CMP AL,72   << 'f' == 0x72 'r'
00380031   0F85 9E000000    JNZ 003800D5
00380037   8A42 04          MOV AL,BYTE PTR DS:[EDX+4]   << 'e'
0038003A   3C 65            CMP AL,65   << 'e' == 0x65 'e'
0038003C   0F85 93000000    JNZ 003800D5
00380042   8A42 0B          MOV AL,BYTE PTR DS:[EDX+B]    << 'l'
00380045   8A62 05          MOV AH,BYTE PTR DS:[EDX+5]   << 'f'
00380048   3AC4             CMP AL,AH   << 'l' == 'f'
0038004A   0F85 85000000    JNZ 003800D5
00380050   8A42 0A          MOV AL,BYTE PTR DS:[EDX+A]    << 'k'
00380053   8A62 04          MOV AH,BYTE PTR DS:[EDX+4]    << 'e'
00380056   3AC4             CMP AL,AH   << 'k' == 'e'
00380058   75 7B            JNZ SHORT 003800D5
0038005A   8A42 03          MOV AL,BYTE PTR DS:[EDX+3]  << 'd'
0038005D   3C 6C            CMP AL,6C   << 'd' == 0x6c 'l'
0038005F   75 74            JNZ SHORT 003800D5
00380061   8A42 01          MOV AL,BYTE PTR DS:[EDX+1]   << 'b'
00380064   3C 61            CMP AL,61   << 'b' == 0x61 'a'
00380066   75 6D            JNZ SHORT 003800D5
00380068   8A42 02          MOV AL,BYTE PTR DS:[EDX+2]   << 'c'
0038006B   8A62 07          MOV AH,BYTE PTR DS:[EDX+7]   << 'h'
0038006E   32C4             XOR AL,AH
00380070   3C 1C            CMP AL,1C    << 'c' ^ 'h' == 0x1c 
00380072   75 61            JNZ SHORT 003800D5
00380074   8A42 02          MOV AL,BYTE PTR DS:[EDX+2]
00380077   24 63            AND AL,63
00380079   8A5A 07          MOV BL,BYTE PTR DS:[EDX+7] 
0038007C   80E3 63          AND BL,63
0038007F   3AC3             CMP AL,BL
00380081   75 52            JNZ SHORT 003800D5
00380083   8A42 09          MOV AL,BYTE PTR DS:[EDX+9]  << 'j'
00380086   2C 10            SUB AL,10    << x = 'j' - 10 
00380088   8A5A 06          MOV BL,BYTE PTR DS:[EDX+6]   << 'g'
0038008B   80C3 11          ADD BL,11  << y = 'g' + 11
0038008E   3AC3             CMP AL,BL     << x == y
00380090   75 43            JNZ SHORT 003800D5
00380095   8A42 07          MOV AL,BYTE PTR DS:[EDX+7]  << 'h'
00380098   2C 07            SUB AL,7    << x = 'h' - 7
0038009A   8A5A 06          MOV BL,BYTE PTR DS:[EDX+6]   << 'g'
0038009D   80C3 11          ADD BL,11   << y ='g' + 11
003800A0   3AC3             CMP AL,BL   << x == y
003800A2   75 31            JNZ SHORT 003800D5
003800A4   8A42 02          MOV AL,BYTE PTR DS:[EDX+2]  << 'c'
003800A7   3C 77            CMP AL,77   << 'c' = 0x77 'w'
003800A9   75 2A            JNZ SHORT 003800D5
003800AB   8A42 0E          MOV AL,BYTE PTR DS:[EDX+E]  << 'o'
003800AE   8A62 0D          MOV AH,BYTE PTR DS:[EDX+D]  << 'n'
003800B1   3AC4             CMP AL,AH     << 'n' == 'o'
003800B3   75 20            JNZ SHORT 003800D5
003800B5   8A42 0F          MOV AL,BYTE PTR DS:[EDX+F]   << 'p'
003800B8   2C 37            SUB AL,37    << 'p' - 37
003800BA   3C 00            CMP AL,0     << 'p' = 0x37 '7'
003800BC   75 17            JNZ SHORT 003800D5
003800BE   8A42 0E          MOV AL,BYTE PTR DS:[EDX+E]   << 'o'
003800C1   2C 33            SUB AL,33     << 'o' - 33
003800C3   3C 00            CMP AL,0      << 'o' = 0x33 '3'
003800C5   75 0E            JNZ SHORT 003800D5
003800C7   8A42 0C          MOV AL,BYTE PTR DS:[EDX+C]   << 'm'
003800CA   2C 31            SUB AL,31    << 'm' - 31
003800CC   3C 00            CMP AL,0     << 'm' = 0x31 '1'
003800CE   75 05            JNZ SHORT 003800D5

Calcul de 'h' :

>>> hex(0x77 ^ 0x1c)
'0x6b'

Table de translation :

a b c d e f g h i j k l m n o p
l a w l e r S k a t e r 1 3 3 7

Password : "lawlerSkater1337".