Coconut CTF: Easy ELF32

From Indonesian Research And Development Center
Jump to: navigation, search

Misi

Pada misi ini, peserta diberikan sebuah file yang memiliki format elf executable 32bit. Peserta diminta untuk mencari flag pada file tersebut dengan terlebih dahulu memasukkan password.


Solusi 1

  • Solusi pertama adalah solusi paling sederhana dan sifatnya trivial yaitu dengan menggunakan strings seperti ini:
% strings easy_f02d1ccea039946fa052b615e3923710
/lib/ld-linux.so.2
S$@1
__gmon_start__
libc.so.6
_IO_stdin_used
exit
strncmp
puts
printf
strlen
__libc_start_main
GLIBC_2.0
PTRhP
Pass
D$ word
D$$:_33
D$(Lf1r
D$,aa_
[^_]
Petunjuk: %s <password>
Salah
Benar
 flag: %sf3b
  • Dari hasil output strings, bisa terlihat beberapa string menarik yang jika digabungkan menjadi Password:_33Lf1raa_ dan jika digunakan sebagai parameter pertama ketika mengeksekusi file soal, maka hasilnya adalah sebagai berikut:
% ./easy_f02d1ccea039946fa052b615e3923710 Password:_33Lf1raa_
Benar
 flag: Password:_33Lf1raa_f3b
  • Bisa terlihat bahwa flagnya adalah Password:_33Lf1raa_f3b.


Solusi 2

  • Solusi ke-2 adalah melakukan static analysis menggunakan objdump seperti ini:
% objdump -d -M intel --prefix-address easy_f02d1ccea039946fa052b615e3923710 | grep '<main'

08048494 <main>      push   ebp
08048495 <main+0x1>  mov    ebp,esp
08048497 <main+0x3>  and    esp,0xfffffff0
0804849a <main+0x6>  sub    esp,0x30                        ; preserve stack
0804849d <main+0x9>  mov    DWORD PTR [esp+0x1c],0x73736150 ; 0x50617373 -> "Pass"
080484a5 <main+0x11> mov    DWORD PTR [esp+0x20],0x64726f77 ; 0x776f7264 -> "word"
080484ad <main+0x19> mov    DWORD PTR [esp+0x24],0x33335f3a ; 0x3a5f3333 -> ":_33"
080484b5 <main+0x21> mov    DWORD PTR [esp+0x28],0x7231664c ; 0x4c663172 -> "Lf1r"
080484bd <main+0x29> mov    DWORD PTR [esp+0x2c],0x5f6161   ; 0x61615f   -> "aa_"
080484c5 <main+0x31> cmp    DWORD PTR [ebp+0x8],0x1         ; apakah argumen (argc) > 1
080484c9 <main+0x35> jg     080484ed <main+0x59>            ; ya, lanjutkan ke -.
080484cb <main+0x37> mov    eax,DWORD PTR [ebp+0xc]         ;                   |
080484ce <main+0x3a> mov    edx,DWORD PTR [eax]             ;                   |
080484d0 <main+0x3c> mov    eax,0x8048610                   ; eax = "Salah"     |
080484d5 <main+0x41> mov    DWORD PTR [esp+0x4],edx         ;                   |
080484d9 <main+0x45> mov    DWORD PTR [esp],eax             ; "Salah"           |
080484dc <main+0x48> call   0804839c <printf@plt>           ; printf("Salah");  |
080484e1 <main+0x4d> mov    DWORD PTR [esp],0x1             ; exit code 1       |
080484e8 <main+0x54> call   080483cc <exit@plt>             ; exit(1);          |
080484ed <main+0x59> lea    eax,[esp+0x1c]                  ; eax = user_pass <-'
080484f1 <main+0x5d> mov    DWORD PTR [esp],eax             ; user_pass
080484f4 <main+0x60> call   0804838c <strlen@plt>           ; strlen(user_pass);
080484f9 <main+0x65> mov    edx,eax                         ; edx = panjang user_pass
080484fb <main+0x67> mov    eax,DWORD PTR [ebp+0xc]         ;
080484fe <main+0x6a> add    eax,0x4                         ;
08048501 <main+0x6d> mov    eax,DWORD PTR [eax]             ;
08048503 <main+0x6f> mov    DWORD PTR [esp+0x8],edx         ;
08048507 <main+0x73> lea    edx,[esp+0x1c]                  ; edx = real_pass
0804850b <main+0x77> mov    DWORD PTR [esp+0x4],edx         ; real_pass
0804850f <main+0x7b> mov    DWORD PTR [esp],eax             ; user_pass
08048512 <main+0x7e> call   080483bc <strncmp@plt>          ; strncmp(user_pass, real_pass, strlen(user_pass));
08048517 <main+0x83> test   eax,eax                         ; hasilnya sama? (eax == 0)
08048519 <main+0x85> je     08048533 <main+0x9f>            ; ya, tampilkan flag ---.
0804851b <main+0x87> mov    DWORD PTR [esp],0x8048629       ;                       |
08048522 <main+0x8e> call   080483ac <puts@plt>             ; puts();               |
08048527 <main+0x93> mov    DWORD PTR [esp],0x1             ; exit code 1           |
0804852e <main+0x9a> call   080483cc <exit@plt>             ; exit(1);              |
08048533 <main+0x9f> mov    eax,0x804862f                   ; <---------------------'
08048538 <main+0xa4> lea    edx,[esp+0x1c]                  ; edx = "Password:_33Lf1raa_"
0804853c <main+0xa8> mov    DWORD PTR [esp+0x4],edx         ; "Password:_33Lf1raa_"
08048540 <main+0xac> mov    DWORD PTR [esp],eax             ; "flag: %sf3b"
08048543 <main+0xaf> call   0804839c <printf@plt>           ; printf("flag: %sf3b", edx);
08048548 <main+0xb4> mov    eax,0x0                         ; exit code 0
0804854d <main+0xb9> leave                                  ; restore stack
0804854e <main+0xba> ret                                    ; return 0;
0804854f <main+0xbb> nop
  • Pada potongan disassembly di atas bisa terlihat instruksi untuk memasukkan password ke stack. Dan jika Anda bertanya mengapa karakternya terbalik, maka jawabannya adalah karena endianness. Untuk merekonstruksi ulang string yang dimasukkan ke stack tersebut, Anda dapat menggunakan cara ini:
% echo -e "\x50\x61\x73\x73\x77\x6f\x72\x64\x3a\x5f\x33\x33\x4c\x66\x31\x72\x61\x61\x5f"
Password:_33Lf1raa_

Atau jika Anda penggemar python:

% python -c 'print "50617373776f72643a5f33334c66317261615f".decode("hex")'
Password:_33Lf1raa_


Solusi 3

  • Cara ke-3 adalah dengan melakukan debugging menggunakan debugger favorit Anda, misalnya gdb. Berikut ini adalah sesi debugging aplikasi pada misi ini:
% gdb ./easy_f02d1ccea039946fa052b615e3923710
Reading symbols from /tmp/easy_f02d1ccea039946fa052b615e3923710...(no debugging symbols found)...done.
gdb> disass main
Dump of assembler code for function main:
   0x08048494 <+0>:     push   ebp
   0x08048495 <+1>:     mov    ebp,esp
   0x08048497 <+3>:     and    esp,0xfffffff0
   0x0804849a <+6>:     sub    esp,0x30
   0x0804849d <+9>:     mov    DWORD PTR [esp+0x1c],0x73736150
   0x080484a5 <+17>:    mov    DWORD PTR [esp+0x20],0x64726f77
   0x080484ad <+25>:    mov    DWORD PTR [esp+0x24],0x33335f3a
   0x080484b5 <+33>:    mov    DWORD PTR [esp+0x28],0x7231664c
   0x080484bd <+41>:    mov    DWORD PTR [esp+0x2c],0x5f6161
   0x080484c5 <+49>:    cmp    DWORD PTR [ebp+0x8],0x1
   0x080484c9 <+53>:    jg     0x80484ed <main+89>
   0x080484cb <+55>:    mov    eax,DWORD PTR [ebp+0xc]
   0x080484ce <+58>:    mov    edx,DWORD PTR [eax]
   0x080484d0 <+60>:    mov    eax,0x8048610
   0x080484d5 <+65>:    mov    DWORD PTR [esp+0x4],edx
   0x080484d9 <+69>:    mov    DWORD PTR [esp],eax
   0x080484dc <+72>:    call   0x804839c <printf@plt>
   0x080484e1 <+77>:    mov    DWORD PTR [esp],0x1
   0x080484e8 <+84>:    call   0x80483cc <exit@plt>
   0x080484ed <+89>:    lea    eax,[esp+0x1c]
   0x080484f1 <+93>:    mov    DWORD PTR [esp],eax
   0x080484f4 <+96>:    call   0x804838c <strlen@plt>
   0x080484f9 <+101>:   mov    edx,eax
   0x080484fb <+103>:   mov    eax,DWORD PTR [ebp+0xc]
   0x080484fe <+106>:   add    eax,0x4
   0x08048501 <+109>:   mov    eax,DWORD PTR [eax]
   0x08048503 <+111>:   mov    DWORD PTR [esp+0x8],edx
   0x08048507 <+115>:   lea    edx,[esp+0x1c]
   0x0804850b <+119>:   mov    DWORD PTR [esp+0x4],edx
   0x0804850f <+123>:   mov    DWORD PTR [esp],eax
   0x08048512 <+126>:   call   0x80483bc <strncmp@plt>
   0x08048517 <+131>:   test   eax,eax
   0x08048519 <+133>:   je     0x8048533 <main+159>
   0x0804851b <+135>:   mov    DWORD PTR [esp],0x8048629
   0x08048522 <+142>:   call   0x80483ac <puts@plt>
   0x08048527 <+147>:   mov    DWORD PTR [esp],0x1
   0x0804852e <+154>:   call   0x80483cc <exit@plt>
   0x08048533 <+159>:   mov    eax,0x804862f
   0x08048538 <+164>:   lea    edx,[esp+0x1c]
   0x0804853c <+168>:   mov    DWORD PTR [esp+0x4],edx
   0x08048540 <+172>:   mov    DWORD PTR [esp],eax
   0x08048543 <+175>:   call   0x804839c <printf@plt>
   0x08048548 <+180>:   mov    eax,0x0
   0x0804854d <+185>:   leave
   0x0804854e <+186>:   ret
End of assembler dump.
gdb> # pasang breakpoint pada pemanggilan fungsi strncmp
gdb> b *(main+126)
Breakpoint 1 at 0x8048512
gdb> # jalankan dengan menggunakan parameter 12345 sebagai password
gdb> r 12345
Starting program: /tmp/./easy_f02d1ccea039946fa052b615e3923710 12345

Breakpoint 1, 0x08048512 in main ()
Missing separate debuginfos, use: debuginfo-install glibc-2.17-20.fc19.i686
gdb> # isi dari register eax adalah parameter password yang kita masukkan
gdb> x/s $eax
0xffffccbc: "12345"
gdb> # sedangkan isi dari register edx adalah password yang benar
gdb> x/s $edx
0xffffc98c: "Password:_33Lf1raa_"
gdb> # sekarang jalankan dengan password yang benar
gdb> r "Password:_33Lf1raa_"
Starting program: /tmp/./easy_f02d1ccea039946fa052b615e3923710 "Password:_33Lf1raa_"

Breakpoint 1, 0x08048512 in main ()
gdb> x/s $eax
0xffffccae: "Password:_33Lf1raa_"
gdb> x/s $edx
0xffffc98c: "Password:_33Lf1raa_"
gdb> # bisa terlihat bahwa passwordnya sudah sama, sekarang lanjutkan eksekusi
gdb> c
Continuing.
Benar
 flag: Password:_33Lf1raa_f3b
[Inferior 1 (process 19969) exited normally]
gdb> # bisa terlihat flagnya adalah "Password:_33Lf1raa_f3b"
gdb> q