2018强网杯pwn之opm解题思路
 
2018强网杯pwn之opm解题思路
0x00 漏洞分析

gets的输入没有控制大小会产生栈溢出,可以修改(变量v6)堆指针
| 
 | 
 | 
查看程序保护,可以看出比较重要的就是leak地址
0x01 漏洞利用
关键点1–>泄露heap地址
- 首先通过第一个栈溢出修改 - role1的指针,修改为- xxxxx0010,然后会将- role1的相关信息存储到- xxxx0010地址。
- 再申请 - role2通过第一个栈溢出修改- role2的指针,修改为xxxxxxx00,让这个地址落在- role1的- name所申请的堆块范围内,然后通过第二次栈溢出修改- role2的指针,将其修改为- xxxxx0010,即将- role2指向- role1。
- 最后程序输出 - name属性,将- role2的- name属性的堆地址泄露出。
注意:要申请一个role0来调整堆的位置好让role1的name所申请的堆块范围内。
关键点2–>泄露程序地址,libc地址
- 在申请role3构造name字段的内容,根据堆地址让其指向role中func_ptr的位置,利用第二次的栈溢出修改role3指针,让其指向伪造的name字段地址,最后可以泄露出func_ptr的值,进而知道程序的加载地址。
注意:这里伪造的role结构体会破坏下一个堆块的size位,这是由于写入punch的值,这里我是通过计算这里的值,通过输入的punch的值来修复,让下次堆块分配得一正常进行,泄露libc的地址与程序的地址类似,这里不再重复。
关键点3–>修改got表
- 利用方式和之前描述的差不多,这次将指针修改到got表附近,让strlen的got得位置落在role的punch位置,这样我们可以修改strlen函数得低四个字节(partial overwrite),将其修改成system地址即可。
0x02 调试和exp
使用gdb结合pwntools调试
申请三个role代码,具体如下:
| 
 | 
 | 
执行过之后的heap情况如两图:


结合上面的图,可以看到0x000055c9c784cd00指向了(由于第一次溢出将堆地址存储到了前一个role的name中)前一个role的name,在将name输出的时候,可以leak到堆地址。
之后再构造如下payload,通过name的值伪造role
| 
 | 
 | 

通过上述的payload可以leak出func_ptr,其它的地方类似,慢慢调试即可。
完整exp如下
| 
 | 
 | 
0x03 运行结果

0x04 总结
根据po师傅的wp和exp,自己动手调试写了一个自己的exp,收获还是蛮大的,遇到了很多问题,都在文中提到过了,希望以后遇到类似的问题可以借鉴。

