j444

Challenge description Link to heading

TitlePlatformLanguageDifficulty
j444Unix/LinuxAssembler1.0

Solution Link to heading

The first part is to get informations about the file:

$ file j444
j444: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, no section header

The second part is to use Ghidra to get assembly of the program:

                     //
                     // segment_0
                     // Loadable segment  [0x8048074 - 0x8048121]
                     // ram:08048074-ram:08048121
                     //
                     **************************************************************
                     *                          FUNCTION                          *
                     **************************************************************
                     undefined processEntry entry()
     undefined         AL:1           <RETURN>
                     ; ECX = CrackMeJosep
                     ; EDX = len -> 0x13
                     entry                                           XREF[3]:     Entry Point(*),
                                                                                  _elfHeader::00000018(*),
                                                                                  _elfProgramHeaders::00000008(*)
08048074 b9 22 91        MOV        ECX,s_Crackme_444_Josep_08049122                 = "Crackme 444 Josep\n"
08048079 ba 13 00        MOV        EDX,0x13
0804807e e8 66 00        CALL       FUN_sys_write                                    undefined FUN_sys_write()
                     ; same to print str Password
08048083 b9 41 91        MOV        ECX,s_Password:_08049141                         = "Password: "
08048088 ba 0b 00        MOV        EDX,0xb
0804808d e8 57 00        CALL       FUN_sys_write                                    undefined FUN_sys_write()
                     ;Sycall READ
                     -> Read the user entry
08048092 b8 03 00        MOV        EAX,0x3
08048097 bb 01 00        MOV        EBX,0x1
0804809c b9 4c 91        MOV        ECX,User_Entry
080480a1 ba 06 00        MOV        EDX,0x6                                          Read only 6 char of the user entry
080480a6 cd 80           INT        0x80
                     End user entry syscall READ
080480a8 e8 49 00        CALL       FUN_flagformat                                   undefined FUN_flagformat(void)
080480ad b9 04 00        MOV        ECX,0x4                                          ecx = 0x4
080480b2 be b4 91        MOV        ESI,flag_ref                                     refflag here
080480b7 bf 96 91        MOV        EDI,flag_transform                               user flag here
080480bc f3 a6           CMPSB.REPE ES:EDI=>flag_transform,ESI=>flag_ref             0x0003c63c (little endian) = 247356
                                                                                     compare each number
080480be 74 11           JZ         flag_ok
080480c0 b9 9a 91        MOV        ECX,s_Bad_password._Try_again!_0804919a          = "Bad password. Try again!\n"
080480c5 ba 1a 00        MOV        EDX,0x1a
080480ca e8 1a 00        CALL       FUN_sys_write                                    undefined FUN_sys_write()
080480cf eb 0f           JMP        exit
                     flag_ok                                         XREF[1]:     080480be(j)
080480d1 b9 35 91        MOV        ECX,s_Well_done!_08049135                        = "Well done!\n"
080480d6 ba 0c 00        MOV        EDX,0xc
080480db e8 09 00        CALL       FUN_sys_write                                    undefined FUN_sys_write()
         00 00
                     exit                                            XREF[1]:     080480cf(j)
080480e0 b8 01 00        MOV        EAX,0x1
080480e5 31 db           XOR        EBX,EBX
080480e7 cd 80           INT        0x80
                     **************************************************************
                     *                          FUNCTION                          *
                     **************************************************************
                     undefined FUN_sys_write()
     undefined         AL:1           <RETURN>
                     Set Crackme josep in ecx, size in edx then print the str
                     FUN_sys_write                                   XREF[4]:     entry:0804807e(c),
                                                                                  entry:0804808d(c),
                                                                                  entry:080480ca(c),
                                                                                  entry:080480db(c)
080480e9 b8 04 00        MOV        EAX,0x4
080480ee bb 01 00        MOV        EBX,0x1
080480f3 cd 80           INT        0x80
080480f5 c3              RET
                     **************************************************************
                     *                          FUNCTION                          *
                     **************************************************************
                     undefined FUN_flagformat(void)
     undefined         AL:1           <RETURN>
                     this function take the dw in entry then * 10 and add the nex
                     FUN_flagformat                                  XREF[1]:     entry:080480a8(c)
080480f6 bd 4c 91        MOV        EBP,User_Entry                                   ebp = user_entry 6char max
080480fb 31 c0           XOR        EAX,EAX                                          eax = 0
                     Loop_user_entry                                 XREF[1]:     0804811f(j)
080480fd bb 0a 00        MOV        EBX,0xa                                          ebx = 0xa
08048102 f7 e3           MUL        EBX                                              eax = eax * 0xa
08048104 89 c3           MOV        EBX,EAX                                          ebx = eax
08048106 8b 45 00        MOV        EAX,dword ptr [EBP]=>User_Entry                  eax = first dw of ebp
08048109 25 ff 00        AND        EAX,0xff                                         eax = eax & 0xff
                                                                                     -> get the value of al
0804810e 83 f8 39        CMP        EAX,0x39
08048111 77 0e           JA         Ret                                              if eax != 0x39
08048113 2c 30           SUB        AL,0x30                                          al = Last int value
08048115 72 0a           JC         Ret                                              if not equal
08048117 01 d8           ADD        EAX,EBX                                          eax = add new value to the old v
08048119 45              INC        EBP                                              EBP += 1
0804811a a3 96 91        MOV        [flag_transform],EAX                             set eax in flag transform for ea
0804811f eb dc           JMP        Loop_user_entry
                     Ret                                             XREF[2]:     08048111(j), 08048115(j)
08048121 c3              RET
                     flag_ref                                        XREF[2]:     entry:080480b2(*),
                                                                                  entry:080480bc(R)
080491b4 3c              ??         3Ch    <                                         the 1st part of the flag
080491b5 c6              ??         C6h                                              the second one
080491b6 03              ??         03h                                              the 3rd
080491b7 00              ??         00h                                              the last one
080491b8 01              ??         01h
080491b9 7d              ??         7Dh    }
080491ba a3              ??         A3h
080491bb 21              ??         21h    !

The most important of this crackme is the flagformat function. After analyse we can understand that this is just a simple way to redo the basic the flag just checking that’s just numbers(with the check 0x39).

Each loop do the same things:

  • multiply by 10
  • Get the first user value (the first number) and add it to the result
  • do this for all 6 numbers

We can conclude our number is not modified.

Then with the comparison the program compare each number one by one. If all equals it’s a win. Else a loose.

In flag ref, ECX = 0X4 so we can take the only 4 values of the flag_ref then tranform in little indian then int.

The reference flag is : 244356.

We can test it:

$ ./j444
Crackme 444 Josep
Password: 247356
Well done!

That’s All Falks!