house of kiwi
提供了另一种刷新IO方式:__malloc_assert
1、setcontext+61的gadget
1 | <setcontext+61>: mov rsp,QWORD PTR [rdx+0xa0] |
主要关注的就是:
1 | <setcontext+61>: mov rsp,QWORD PTR [rdx+0xa0] |
布置好rdx+0xa0 以及 rdx+0xa8 也就控制了rsp,后续ret就可以控制程序流了
2、IO
也是这周刚好参加国资社畜师傅的课,对IO了解的更详细些,这里是利用_malloc_assert
去调用fflush函数,也就会执行跳表中的__sync
指针
3、house of kiwi
因为进入IO的__sync
之后会发现rdx固定为_IO_helper_jumps,所以控制_IO_helper_jumps+0xa0、_IO_helper_jumps+0xa8
去调用setcontext+61就可以控制程序流
使用条件
1、能够触发__malloc_assert
(top_chunk不满足申请内存的size)
2、能够任意写,修改_IO_file_sync和IO_helper_jumps + 0xA0 and 0xA8
将__sync中地址修改为setcontext+61,将IO_helper_jumps+0xa0 和 +0xa8分别修改为orw和ret地址
[nepctf2021]NULL_FXCK
参考博客:
2.32 菜单堆题 沙盒禁用execv、保护全开 全是新知识 猛猛学
IDA:
进入菜单前:相当于ban掉了malloc_hook 以及 free_hook
add:申请大小 0x100~0x2000,输入会在最后做截断,没有溢出、也不能去连带打印chunk中内容
Modify:(edit)存在off-by-null
delete:没有uaf漏洞
show:虽然用的write打印,但strlen是会截断00的
思路及过程(学习其他师傅wp)
堆风水绕过unlink检查
这题ban了hook、还禁用了execve 只能打orw,所以需要去控制程序流
有off-by-null,第一反应是去修改size然后unlink,不过没有uaf漏洞,这里就是考验极致的堆布置能力了。
首先是目的就是绕过unlink的检查:bck->fd == P ;fwd-> ==P ,以及要chunksize(P) == pre_size
当我们连续放入三个chunk时,中间的chunk1的fd、bk就布置好了,关键就在于chunk0的fd以及chunk2的bk
1 | #这里多个chunk是为后续准备的 |
因为只能通过add以及delete去修改堆中的内容,所以原chunk1肯定是不能去动的,这里巧妙的在chunk1上方多申请了一块chunk1_up,将这两块地址free合并再切割将原chunk1的fd、bk放到新chunk1_up的底部,当然为了后续操作方便,这里chunk大小的设置将chunk1的地址控制为00结尾,之后就可以将新chunk1地址链入chunk0 bk、chunk2 fd,然后修改末字节就可以达到目的
1 | delete(2) #会和chunk3 合并 (0x430+0x440 = 0x870) |
然后修改chunk0的bk、将新chunk1链入到chunk0,然后利用add中的截断去修改末字节
1 | #修改原chunk0的bk |
然后同样的去修改chunk2的bk
1 | add(0x418) #原chunk3+0x20 3 |
然后就可以修改pre_size 触发unlink,实现堆覆盖
1 | #修改chunk7的pre_size=0xc90,size=0xa00 |
pre_size in_use位 chunk的fd、bk都准备好了
unlink成功
后面截图地址与上面有偏差,一步步调到add(0x208)就断了 但直接断在后面就没问题 不清楚为什么qwq)
泄露地址
有了堆重叠,但地址还没泄露的,直接show的话末地址为00,泄露不出来,放入largebin再泄露
1 | pay = flat(0,0,0,p64(0x421)) |
任意地址写入的实现
现在虽然有了堆重叠,但chunk大小不能用到tcache bin,所以没办法任意地址写入,这里师傅提供了一种新方式,tcachebin会有一块存tcache struct的chunk,也就是heap_base的,而这块地址是存在TSL段的一块地址上
所以只要劫持该指针为我们可控制地址,就可以控制tcache,也就可以任意地址写入了
这里利用largebin attack向该指针写入堆块地址就可以了
这里提前在heap_adr+0x8e0处写入了 orw
1 | pay = b'a'*0x208+p64(0x431)+b'a'*0x428+p64(0x211)+b'a'*0x208+p64(0xa01) |
但是在gdb中查看不到,写好偏移,然后走house of kiwi就可以执行orw了
1 | add(0x410) #11 |
malloc函数过程
完整EXP
1 | from pwn import * |
- 本文作者: 1uckyc
- 本文链接: https://1uckyc.github.io/2023/09/03/house-of-wiki学习以及复现/