步骤:泄漏mmap->挟持rbp->劫持stdin->挟持setbuf的got
这里需要用到的知识点是scanf特性,read参数控制,execv使用(高版本libc建议不用system,因为第一个就是system的16字节对齐问题,第二个就是system对栈空间要求相对较高很可能覆盖掉其他参数导致运行失败而卡住,具体去看源码即可)
ps:本题所有的one_gadget均不瞒住条件,libc是
2.31-0ubuntu9.7_amd64
前置知识:scanf遇到运算符的时候会跳过输入执行下一次,也不会写入覆盖掉内存里面的内容。read参数通过rbp加偏移寻址,如果控制rbp就能任意地址写,而且是无限写♾️。execv一般来说需要三个参数,但是其实后两个参数并不一定要传入0,甚至特定条件下可以不用理会,关于execv的第二个参数数组,存放的东西对于程序没有影响,第二个以后存放的就是execv使用的参数。
先看程序开启的保护
main程序代码:
really_fight:
one_kick:
before_before_punch:
before_punch:
one_punch:
程序只有one_punch有溢出并且刚好只能溢出到返回地址,也就是得考虑栈迁移布置rop,但是如果使用leave;ret迁移到bss或者其他地方都没有执行权限,如果bss上布置libc里面的rop链的话是无法返回到上面去的(因为ret-->bss-->libc地址-->汇编这种是不行的),这个时候就得用非常规迁移了,但是问题来了,64位程序,只能写入0x20,不能构造rop,这时候就得想办法无限写了,先上exp:
最终获得稳定的shell
首先
通过scanf的特性泄漏mmap的地址,因为mmap靠近libc,所以可以通过mmap泄漏libc的地址
然后
泄漏libc中的execv和sh,布局在bss+0x10(stdin的地址)上一个libc中的sh,通过劫持read的rbp达到任意地址写,通过修改rbp位置可以达到无限写,然后篡改setbuf的got表为execv即可
原文始发于微信公众号(由由学习吧):极限状态下缓冲区溢出
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论