06. 格式化字符串漏洞发生的条件
1.实例程序1printf2.c
正常源码:
1 |
|
代码解释:可以知道第一个%s对应hello world!,%d对应233,第二个%s对应转义字符\n换行
提权:chmod 777 print2.c
编译:gcc -m32 -o printf2 printf2.c
调试:gdb printf2
查看mian函数:disass main
然后再printf函数加断点:b *0x56555552
再运行:
可以清楚的看到printf()函数里面的参数由于函数调用_cdecl被从右到左压栈
0xe9转化位十进制就是233
然后其实就是正常对应输出:
2.实例程序2printf3.c
漏洞源码:
1 |
|
代码解释:第一个%s对应输出hello world,%d对应233,第二个%s对应转义字符\n换行,后面的格式化字符就对应后面堆栈里的随机内容了,注意%s$是输出对应第三行地址里面的内容,也就是换行\n
后面正常和上面一样的操作不多解释
哦对,加断点之前注意一个细节,注意运行完一遍,把地址调整号好正确
查看main函数,继续加断点:
运行:
前面的对应关系我们已经知道,但是分析后面的对应关系:
第一个%x对应输出后面的ffffd120
第二个%x又对应下一行0
可以看到后面的堆栈就看不到连续被省略,此时用命令:stack 0x20 查看20行堆栈
所以可以继续后看连续的堆栈地址:
第三个%x默认对应还是0
最后那个%3$s其实就是打印第三个参数的意思,所以也是换行
所以我们就可以回顾一下刚才执行完后为什么输出那些东西了。
注意:如果还有看不到的堆栈地址内容可以用以下方式查看:
这是x类命令概念
3.程序实例3printf4.c
源代码:
1 |
|
同上略!
fgets() 的原型为:
include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
1 | s 代表要保存到的内存空间的首地址,可以是字符数组名,也可以是指向字符数组的字符指针变量名。 |
此时先执行一次:
可以看到我们输入格式化字符串的话,会打印处对应堆栈内的随机内容!
然后下断点,还是要注意细节哦,先运行,地址才不是偏移:
b *0x56555607
运行:
单步执行+输入:
再观察:
堆栈也许看的不够,那可以像上面一样:stack 0x20 查看32行
由于一行堆栈只能存4字节内容,所以从0xffffd0a8到0xffffd0b4是连续储存我们输入的内容的。
后面继续单步执行到+68行,还会遇到判断标志位跳转
这里之前所过不多说:记得修改命令:set $eflag = 数值
+77行,执行printf函数,执行前先看堆栈详情:
可以看到,执行原理也是和上面的程序一样,字符原样输出,格式化字符接续匹配堆栈参数!
最后面其实还要注意fgets()函数会自动添加的换行操作!