直接快进到2.35,毕业有望了(逃
house of cat是由catfly师傅提出的,通杀2.35及其以下的牛掰链子,利用简单,只需要一个largebin attack,但是杀伤力巨大,可以执行任意函数。这个链子也被catfly师傅出题成为了今年qwb的pwn题。这链子里主要的思路与开赛前一天,roderick师傅发表的house of apple2相似,所以这里就以我的例题为标题,讲一讲如何利用 _wide_vtable 来劫持程序流。
一、🐱和🍎的原理
通过拜读roderick师傅和catfly师傅的文章,我们可以开始分析🐱和🍎的原理。
1、vtable check
首先在之前学习FSOP中我们学习到了伪造IO的vtable表,程序调用vtable对应偏移处的函数时,劫持程序流。但是在glibc-2.24之后,加入了一个 IO_validate_vtable 函数。
在stderr,stdout,stdin这三个IO结构体使用的是 IO_file_jumps 这个虚函数表
以_IO_file_overflow
调用为例,我们可以看到其部分宏定义如下:
1 |
其中调用的IO_validate_vtable会check此时的vtable是否在合法区域。
这意味着我们不能直接修改vtable为任意可控地址,但是却可以在vtable允许的范围内反复跳跃。所以vtable里的函数我们还是能随便调用。
在2.27之前,我们可以使用 _IO_str_overflow 与 _IO_str_finish中的函数指针,但是在这之后,其函数指针被替换成了malloc和free,利用失效。
2、 _wide_vtable
_wide_vtable 可谓是🐱和🍎的重中之重。
首先我们看一下这个wide vtable
1 | struct _IO_wide_data |
这里面同样存在一个vtable表,并且他的调用和我们所了解过的vtable一样,通过宏调用,根据vtable的地址+偏移索引到要调用的函数。
但是!和上面的又有那么一点关键不同
1 | #define _IO_WOVERFLOW(FP, CH) WJUMP1 (__overflow, FP, CH) |
它的宏调用里没有check vtable的合法性
这下可以找回2.23初恋版本的感觉了。只要我们伪造_IO_wide_data,进而控制wide 的vtable表,就可以调用任意函数。
以上就是🍎2的利用,🐱的利用也大致利用了上述思想,劫持了wide vtable最后调用我们想要的函数。关键就是这个的宏调用不check。
所以我们可以理解🐱是🍎的一条具体链子。
3、🐱
这题house of cat我是利用🐱的链子来打orw,这里就先讲一下🐱的IO构造有哪些要点。
1 | fake_io_addr=heapbase+0xb00 # 伪造的fake_IO结构体的地址 |
首先这里的rax我们需要结合汇编来理解
我的图图:
我们可以看到**mov rax, qword ptr [rdi + 0xa0]**
这里会将rax
赋值成**rdi + 0xa0**
这里是rax1,在这之后会将**rax+0x20**
的值赋值给rdx
,所以我们可以控制rdx
,然后 **mov rax, qword ptr [rax + 0xe0]**
再一次赋值rax
为rax2
,最后call了这个*rax2*+0x18
的地址。
构造好的IO结构大致如下
4、🍎
🍎2的IO构造大致如上,只是将就不多赘述。值得一提的是,🍎1可以充当打一次largebin attack,可以利用🍎1配合house of emma来打这题。🍎3还没康,留个坑(x
二、例题-2022强网杯初赛-house of cat
一题套了IOT交互界面的堆题(有一说一就看上去炫酷了
1、程序分析:
2.35开了沙箱
在程序每次进入菜单的时候都会进行一次对tcache_bins的赋值, 禁了打tcache bins进行任意地址申请的方法
存在UAF,但只能申请largebin
edit函数只能用两次
2、利用方法:
这题有三种方法
1、走🍎2,直接orw
2、🍎1结合house of emma
3、只用house of emma(需要堆风水一下)
我是用🍎2,打两次largebin attack,一次打stderr,一次打top size触发kiwi走IO。
3、exp:
1 | from pwn import * |
下班!
pwn太有意思了qwq