主程序就是这样的,能看到有一个printf的格式化字符串漏洞
sprintf 相当于把参数替换了之后的格式化字符串送入了第一个参数,也就是format
首先,没有后门也没有系统函数,要用格式化字符串泄露出某个libc函数,来获得libc基址
然后,仔细算一下 s 和 format 两个参数,都没有溢出,,也没有函数能写进got表,,所以还是再次利用格式化字符串漏洞通过%n来写入数据
先看一下我们输入的数据在栈上的布局:
这里面
1 是格式化字符串的指针,指向了栈上 format的位置,,
2 是我们输入东西的位置的指针
3 是我们输入的东西存储的地方,,注意,以这个程序为例,他储存的地方是 0xfffcdaf 并不是一个对齐的地址,,覆盖的时候要注意
我们运行程序,输入 %1$s ,,Reapeater:后面输出的是 Reapeater这一句
所以这样计算偏移的话,我们输入的东西的位置+1 就是格式化字符串的 第8个参数
之后通过构造,将要泄露的got地址写进第8个参数的位置,再通过 %8$s 泄露
之后我们要覆盖一个函数的got表内容为system
网上一些人做的是覆盖printf的
但是我这么做一直报错,可能是因为循环之后还会用到printf,但是里面的参数是 Please … 这一句,system无法执行吧
我覆盖的是strlen函数,因为它的参数我们可控
之后就是怎么写入了
之前做过这样的题,,只是用 %好多c 和 %n 写入,但是这次写的数是个地址,有些大了可能就不行,会发生超时什么的