1. 格式化字符串漏洞概述
格式化字符串漏洞(Format String Vulnerability)是由于程序直接使用用户输入作为格式化参数,导致攻击者可以泄露内存信息或修改程序数据。
1.1 格式化字符串的原理
在 C 语言中,printf
、sprintf
、fprintf
等函数用于格式化输出。例如:
printf("Hello %s!", name);
如果 name
由用户输入控制,且 printf
没有指定格式化参数,可能会引发漏洞:
printf(name);
攻击者可以输入 %x %x %x
,直接读取栈中的内容。
2. 格式化字符串漏洞示例
2.1 漏洞代码
#include <stdio.h> #include <string.h> void vulnerable_function(char *input) { char buffer[64]; strcpy(buffer, input); printf(buffer); // 漏洞点 } int main(int argc, char *argv[]) { if (argc > 1) { vulnerable_function(argv[1]); } return 0; }
2.2 编译并运行
gcc -fno-stack-protector -o vuln_fmt vuln.c ./vuln_fmt "%x %x %x %x"
3. 格式化字符串信息泄露
3.1 读取栈数据
格式化字符串漏洞可用于泄露程序中的敏感信息,如栈地址、返回地址等。
./vuln_fmt "%p %p %p %p"
如果返回类似 0xbffff7dc 0x080484f4 0xb7fdc000 0x080484d0
,则说明栈数据被泄露。
4. 格式化字符串写入利用
4.1 利用 %n
修改内存
格式化字符串的 %n
允许将写入的字符数存入指定地址。
int main() { int target = 0; printf("%x %x %x %n", &target); printf("Target = %d\n", target); return 0; }
攻击者可利用 %n
修改 GOT
表,劫持函数执行流。
4.2 修改返回地址
-
找到
printf
的 GOT 地址:objdump -R ./vuln_fmt | grep printf
-
构造输入,使
printf
的 GOT 指向system()
,劫持执行/bin/sh
。
5. 练习题
-
使用
gdb
观察printf("%x %x %x %x")
的输出,理解栈布局。 -
使用
%n
修改内存值,使程序行为发生变化。 -
研究
GOT
劫持技术,并尝试利用格式化字符串漏洞执行system("/bin/sh")
。
6. 总结
-
了解格式化字符串的工作原理。
-
通过
%x
和%p
泄露内存信息。 -
通过
%n
进行内存修改。 -
了解
GOT
劫持的利用方式。