格式化字符串漏洞的补充
0-Preview
今天原本是👴们的英雄联盟时间,不用学习的。但是看着pwn就剩一个题太难受了,强迫症作祟,游戏都不想打了。
1-CGfsb
很明显啊,还是个 printf 的漏洞,不会还是格式化字符串漏洞吧,那这个题就可以秒了。
一看伪代码,还真是这个漏洞。
原理可以去看 国庆七天pwn的第二天。
解题思路:
利用格式化字符串漏洞 %p 泄露栈空间计算出偏移量
将要修改数据的地址当做参数,赋值给 name
最后利用 %n 来写入栈,修改 s 的值。
测试一下偏移量:
数了下,是 十 个偏移,接下来就可以写exp了。
1.1 exp
这道题还是有不一样的地方
1 | PYTHON |
2-疑问
这个题和 string 有啥不同的地方?
为什么 string 可以利用上一次输入地址,而这个题 不行。
做完这个题,我就一直在想。上一个string,也是第一次做格式化字符串漏洞,我记得是可以在一个输入点输入地址信息,然后在下一个输入点进行漏洞利用。
但是这个题就不行。这个必须搞明白咋回事。
为什么手动gdb和exp出来的地址不一样?
2.1-ida分析
Int64 意思是64位整数(64bit interger), 相当于 long long 占8个字节
DWORD 代表 unsigned long 32位 四字节
%ld 表示数据按十进制有符号长型整数输入或输出。
区别:
1、string 是 64位 程序,这个CGfsb是32位程序
2、定义不同:string:int64 v2 // _isoc99_scanf(“%ld”, &v2);
CGfsb:DWORD buf[2] // read(0, buf, 0xAu);
3、exp的传参方式不同:
1 | PYTHON |
一个是直接传字符串,一个用 p32 打包。
2.2-测试一下
由于我的底层学的还不是很好,需要实践一下。
测试一下,数组在栈中的存储方式、scanf和read读入有啥区别。
写个代码:
1 | C |
没问题啊,说明不是这里。
关于手动调试gdb结果不同的那个问题。
chumen👴一针见血:
你可以看下al
aslr
会看到is off
aslr on会开起来
在gdb命令行输入
1 | BASH |
这下地址就随机了,虽然目前还没发现有🥚用
3-失败
虽然没有用另一个办法打通,但是明白了为什么打不通。
这道题的name采用的是数组来存储。
入栈时会分成两半入栈,我输入的 aaaa 直接变成了两个 6161 。
并且设置了read读入长度最多为10位,限制了我们将一个地址分成两份的操作。
所以说这里不能写入地址。