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,收获还是蛮大的,遇到了很多问题,都在文中提到过了,希望以后遇到类似的问题可以借鉴。