2

I'm trying to understand the behaviour of the code below so I can determine what input will trigger the "YOU DID IT !~!" string (at the end of the program instructions):

.text:00C21034 Buf= byte ptr -6Ch
.text:00C21034 var_68= byte ptr -68h
.text:00C21034 var_4= dword ptr -4
.text:00C21034
.text:00C21034 push    ebp
.text:00C21035 mov     ebp, esp
.text:00C21037 sub     esp, 6Ch
.text:00C2103A mov     eax, ___security_cookie
.text:00C2103F xor     eax, ebp
.text:00C21041 mov     [ebp+var_4], eax
.text:00C21044 push    ebx
.text:00C21045 push    offset aPleaseEnterThe          ; "Please enter the password: "
.text:00C2104A call    sub_C21006
.text:00C2104F xor     ebx, ebx
.text:00C21051 push    ebx
.text:00C21052 call    ds:__acrt_iob_func
.text:00C21058 push    eax                             ; File
.text:00C21059 lea     eax, [ebp+Buf]
.text:00C2105C push    64h                             ; MaxCount
.text:00C2105E push    eax                             ; Buf
.text:00C2105F call    ds:fgets
.text:00C21065 lea     ecx, [ebp+Buf]
.text:00C21068 add     esp, 14h
.text:00C2106B lea     edx, [ecx+1]
.text:00C2106E
.text:00C2106E loc_C2106E:                             ; CODE XREF: sub_C21034+3F↓j
.text:00C2106E mov     al, [ecx]
.text:00C21070 inc     ecx
.text:00C21071 test    al, al
.text:00C21073 jnz     short loc_C2106E
.text:00C21075 sub     ecx, edx
.text:00C21077 cmp     ecx, 5
.text:00C2107A jnz     short loc_C210C3
.text:00C2107C mov     [ebp+var_68], bl
.text:00C2107F
.text:00C2107F loc_C2107F:                             ; CODE XREF: sub_C21034+5E↓j
.text:00C2107F mov     eax, ebx
.text:00C21081 and     eax, 3
.text:00C21084 mov     al, [ebp+eax+Buf]
.text:00C21088 xor     byte_C23018[ebx], al
.text:00C2108E inc     ebx
.text:00C2108F cmp     ebx, 0Ah
.text:00C21092 jb      short loc_C2107F
.text:00C21094 mov     ecx, offset byte_C23018
.text:00C21099 mov     edx, offset loc_C23024
.text:00C2109E mov     eax, [ecx]
.text:00C210A0 cmp     eax, [edx]
.text:00C210A2 jnz     short loc_C210C3
.text:00C210A4 mov     eax, [ecx+4]
.text:00C210A7 cmp     eax, [edx+4]
.text:00C210AA jnz     short loc_C210C3
.text:00C210AC movzx   eax, byte ptr [ecx+8]
.text:00C210B0 cmp     al, [edx+8]
.text:00C210B3 jnz     short loc_C210C3
.text:00C210B5 push    offset aYouDidIt                ; "YOU DID IT !~!\r\n"
.text:00C210BA call    sub_C21006
.text:00C210BF xor     eax, eax
.text:00C210C1 jmp     short loc_C210D0
.text:00C210C3 ; ---------------------------------------------------------------------------
.text:00C210C3
.text:00C210C3 loc_C210C3:                             ; CODE XREF: sub_C21034+46↑j
.text:00C210C3                                         ; sub_C21034+6E↑j ...
.text:00C210C3 push    offset aOhhhhNooTryAga          ; "Ohhhh noo... try again.\r\n"
.text:00C210C8 call    sub_C21006
.text:00C210CD xor     eax, eax
.text:00C210CF inc     eax


NOTE:
The goal here is to find the correct input. I know that I can just put the IP where I want and make the program print it.


What I understood so far:

The program asks for input in this instruction:

.text:00C2105F call    ds:fgets

After that, it runs a loop that counts how many chars are in the input, including the "new line" char at the end (when the user gives input and presses "enter"):

.text:00C2106E loc_C2106E:                             ; CODE XREF: sub_C21034+3F↓j
.text:00C2106E mov     al, [ecx]
.text:00C21070 inc     ecx
.text:00C21071 test    al, al
.text:00C21073 jnz     short loc_C2106E

Then, it subtracts the address of the last input char and the address of the first input char to determine the input's length:

.text:00C21075 sub     ecx, edx
.text:00C21077 cmp     ecx, 5
.text:00C2107A jnz     short loc_C210C3

If the input length is different than 5 (including the "new line" char), then it jumps to this label that prints out "Ohhhh noo... try again." and terminates the program:

.text:00C210C3 push    offset aOhhhhNooTryAga          ; "Ohhhh noo... try again.\r\n"
.text:00C210C8 call    sub_C21006

if the input length is exactly 5 (including the "new line" char), then it proceeds to this instruction that removes the "new line" char from the end of the input string, such that instead of 'A' hexa, there will be '0' hexa (bl initially have a value of 0):

.text:00C2107C mov     [ebp+var_68], bl

So, if the input's length is 5 (including the new line char), it should proceeds to the code below. It's a loop that runs 10 times. ebx is initially 0, and it keeps running until ebx = 0A hexa = 10 decimal:

.text:00C2107F loc_C2107F:                             ; CODE XREF: sub_C21034+5E↓j
.text:00C2107F mov     eax, ebx
.text:00C21081 and     eax, 3
.text:00C21084 mov     al, [ebp+eax+Buf]
.text:00C21088 xor     byte_C23018[ebx], al
.text:00C2108E inc     ebx
.text:00C2108F cmp     ebx, 0Ah
.text:00C21092 jb      short loc_C2107F

Now, the thing about this loop is that the following instruction guarentees that eax will always have values in the range 0-3:

.text:00C21081 and     eax, 3

So, supposed I entered the input "G00D", that loop will XOR each char of the input string with every char of the string "G00D job!" (byte_C23018 that appears in the XOR instruction stores this string, see "P.S" at the end of the post), here is a demo of this loop ('20h' is the ascii value of the "space" char):

  eax = 0  |  eax = 1  |   eax = 2  |  eax = 3  |    eax = 0    |  eax = 1  |etc
G XOR G = 0|0 XOR 0 = 0| 0 XOR 0 = 0|D XOR D = 0|G XOR '20h' = g|0 XOR j = z|etc

After that loop I'm starting to struggle.
The 2 labels in the code below are 6 addresses away from each other:

.text:00C21094 mov     ecx, offset byte_C23018
.text:00C21099 mov     edx, offset loc_C23024

But they have to point to exactly the same address so this "cmp" instruction that comes after it will succeed:

.text:00C210A0 cmp     eax, [edx]

Otherwise - the condition for the "jnz" instruction below is met, and it jumps to that label that prints the "oh no try again" string:

.text:00C210A2 jnz     short loc_C210C3
.text:00C210C3 push    offset aOhhhhNooTryAga          ; "Ohhhh noo... try again.\r\n"
.text:00C210C8 call    sub_C21006

Any suggestions or ideas? did I understand something wrong?

Thanks in advance!


P.S:
This is where the "G00D job!" is stored. Notice that the "G" is '47h'

.data:00C23018 byte_C23018 db 47h                      ; DATA XREF: sub_C21034+54↑w
.data:00C23018                                         ; sub_C21034+60↑o
.data:00C23019 a00dJob db '00D job!',0
.data:00C23022 align 4
.data:00C23024
.data:00C23024 loc_C23024:                             ; DATA XREF: sub_C21034+65↑o
.data:00C23024 add     eax, 62657D71h
.data:00C23029 sub     esp, [edx]
.data:00C2302B inc     ebx
.data:00C2302C arpl    [eax], ax

And if I input "G00D", it stores it here:

debug007:00BBF8A0 db  47h ; G
debug007:00BBF8A1 db  30h ; 0
debug007:00BBF8A2 db  30h ; 0
debug007:00BBF8A3 db  44h ; D
1

You were almost there.

But they have to point to exactly the same address so this "cmp" instruction that comes after it will succeed

This statement is incorrect. Not addresses are being compared, but the data at each. The code, starting from .text:00C21094 compares 13 subsequent bytes at byte_C23018 with their counterparts at loc_C23024.

So, to get the correct password, we have to investigate them. It's easy to see, that at the start of the program, they are not the same, so they have to be modified at some point. The only place where it happens is the loop at loc_C2107F. It xors subsequent letters of your password with the letters of "G00D job!" string. As you have pointed out, password has to have length 5, including \n character, so it makes sense that the loop only uses first four bytes of the password.

But xor is invertible operation; in other words, if A xor B = C, then A = C xor B, since B xor B = 0 and A xor 0 = A.

In your case, A is the password you are providing, B is the "G00d job!" string, and C is the string at loc_C23024. So, to find relevant A you just need to xor B with C.

| improve this answer | |
  • AMAZING! That did the job. Thank you so much!!! This is the accepted answer. – Elyasaf755 Dec 29 '19 at 0:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.