22年国赛华南赛区的一道堆题。网上都没搜到wp,感觉确实题目所考IO_FILE利用,相对栈和堆来讲,可能很多pwn手学了用的也很少。
首先看一下程序保护:
经典的保护全开。
题目libc版本为2.33,算是比较新了,不过还有malloc hook和free hook可以打。
看一下程序逻辑:
经典菜单题。
add函数最多堆块下标为15,即16个可用下标,heap数组和size数组分别用于保存堆指针和堆块大小。
show函数查看堆块内容,没啥问题。
delete函数free堆块并清零数组内容,无漏洞。
edit函数存在下标整数溢出漏洞,其中v0作为heap数组下标被强转为int,可能出现负数的情况。edit_flag初始化为1,即只可以edit一次。
此外程序还有一个输入299可以进入的特殊函数
跟edit差不多,edit之后有一个sandbox
程序开完沙箱之后直接exit了,而且看这个沙箱是非常强的沙箱,封死了exit_hook这种IO攻击思路。感觉这个沙箱是一个无法绕过的沙箱了,笔者自己的攻击没有用到这个299进入的“后门函数”,不知道这个函数有什么用,如果有利用这个函数攻击成功的师傅可以私信我交流。
故笔者将该“后门函数”当作废后门来看。没有使用。
看一下bss段布局:
漏洞分析如下:
1、这里注意到0x4008处存在一个指向自己的指针,算一下偏移,为-11,通过edit下标为-11的堆块可以修改0x4008处的内容,进而可以修改到edit_flag,实现无限次edit。
2、值得注意的是当heap下标在-16<idx<0的时候,对应的size数组也会往上取,取到heap中的数据当作size,若我们提前布置对应处的heap指针,则会将一个堆地址当作size进行读取,相当于有一个非常大的数据读入点。
3、heap和size都在bss段,上面紧邻着stdout、stdin、stderr三个IO结构体指针,其中stdout对应heap[-8],可以通过edit的漏洞达到修改stdout结构体的效果。
攻击思路整理:
1、首先布置满16个chunk,填满heap数组,为的是后面调用edit函数时可以取到对应的size。
2、借助0x4008处的指针修改edit_flag,得到无限次edit的能力。
3、第一次编辑stdout结构体,通过IO_FILE attack,stdout的任意地址读能力,泄露libc地址。进而得到free hook和system的地址。
4、第二次边集stdout结构体,通过IO_FILE attack,stdout的任意地址写能力,计算偏移向free_hook中写入system的地址。
5、free一个内容为/bin/sh的堆块,getshell。
完整攻击脚本:
【说明】脚本中关于第二次stdout任意地址写的操作,需要修改的是_IO_write_ptr和_IO_write_end,通过控制两个指针的值使得show函数的输出恰好填入free hook的位置即可。
脚本执行结果:
成功getshell。
此题目为2022 ciscn华南赛区pwn最后一题,至此4/4全部复现完毕。
By Del0n1x
Keyboard
风车库 2023-01-04
no_cyan 2023-01-01