格式化字符串漏洞

漏洞原因:

程序将格式化字符串的输入权交给用户,printf函数并不知道参数个数,它的内部有个指针,用来索检格式化字符串。对于特定类型%,就去取相应参数的值,直到索检到格式化字符串结束。所以没有参数,代码也会将format string 后面的内存当做参数以16进制输出。这样就会造成内存泄露。

printf(”格式化字符串”,参数…)
该printf函数的第一个参数是由格式化说明符与字符串组成,用来规定参数用什么格式输出内容。
参数:
%d – 十进制 – 输出十进制整数
%s – 字符串 – 从内存中读取字符串
%x – 十六进制 – 输出十六进制数
%c – 字符 – 输出字符
%p – 指针 – 指针地址
%n – 这个格式化字符串,它的功能是将%n之前打印出来的字符个数,赋值给传入的指针。通过%n我们就可以修改内存中的值了。

内存泄露

!!!重点
64位下,函数前6个参数依次保存在rdi、rsi、rdx、rcx、r8和r9寄存器中(,而从第7个参数开始,依然会保存在栈中。故若使用”x$”,则从x=7开始,我们就可以指向栈中数据了。

实践一下:
file

先在printf处下个断点,然后看一下第6,7,8个参数,因为相对直观一点。file
file

看一下第8个参数
file

file

这样不给printf参数但是要让它输出十六进制字符时,它就会把相应地址处的值输出,导致内存泄露

覆盖栈内存

这里才用到%n,%n的作用具体情况如下
file

b的初值为0,但是可以通过输入i的值来改变b的值
file

输入7个a,结果b的值变成了7

发表评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据