Bootstrap

格式化字符串漏洞(Format String Vulnerability)

格式化字符串漏洞(Format String Vulnerability)是程序中因不当处理格式化字符串参数而导致的一类安全漏洞,常被攻击者利用来读取内存数据、篡改程序执行流程,甚至执行任意代码。以下是对其原理、利用方式及防御措施的详细解析:

一、漏洞原理

1. 格式化函数基础

C语言中的 printfsprintffprintf 等函数通过格式化字符串(如 %s%d%x 等)控制输出格式。例如:

printf("Value: %d, Address: 0x%x\n", value, &value);

函数会根据格式字符串从栈中依次读取参数并格式化输出。

2. 漏洞触发条件

当程序将用户输入直接作为格式化字符串参数时,攻击者可构造恶意输入控制格式化字符串:

char user_input[100];
scanf("%s", user_input);  // 用户输入可控
printf(user_input);       // 漏洞点:直接使用用户输入作为格式字符串

若用户输入包含 %x%s 等格式化符,printf 会从栈中读取本不属于它的数据。

二、漏洞利用方式

1. 信息泄露(Read Memory)
  • 读取栈数据:通过 %x%p 等泄露栈内容。

    // 用户输入 "%08x.%08x.%08x.%08x"
    // 输出栈中后续的4个参数(以8位十六进制显示)
  • 读取任意地址数据:结合 %s 和栈上的地址指针。

    // 输入 "AAAA%x%x%x%x%x%x%s",若栈中某处存有地址0x41414141("AAAA"),%s会尝试读取该地址内容
2. 内存写入(Write Memory)
  • 利用 %n 写入数据%n 会将已输出的字符数写入指定地址。

    // 输入 "\x78\x56\x34\x12%2048c%n",将0x804(2048+4=2052)写入地址0x12345678

    通过多次 %n 可精确控制写入的值(如修改返回地址、GOT表等)。

3. 代码执行

通过覆盖关键内存地址(如函数指针、GOT表项),劫持程序执行流程,跳转到shellcode或ROP链。

三、漏洞利用示例

1. 修改变量值

假设存在以下漏洞代码:

int auth_flag = 0;
char buffer[100];
gets(buffer);  // 用户输入直接传入printf
printf(buffer);

攻击者输入:

\x24\xa0\x04\x08%2048c%n

\x24\xa0\x04\x08 是 auth_flag 的地址(假设为0x0804a024)。

%2048c 输出2048个字符,%n 将已输出的字符数(2048 + 4 = 2052)写入 auth_flag 的地址,将其值改为2052。

四、防御措施

  1. 严格使用静态格式字符串

    printf("%s", user_input);  // 正确:将用户输入作为参数,而非格式字符串
  2. 编译选项启用警告

    GCC中开启 -Wformat-security,检测不安全的格式化函数用法。
  3. 输入过滤

    检查用户输入中是否包含 % 字符(需谨慎,可能被绕过)。
  4. 使用安全函数

    替换 printf 为 snprintf 等限制长度的函数。
  5. 内存保护机制

    启用ASLR(地址空间布局随机化)、NX(堆栈不可执行)等缓解技术。

时光匆匆,一篇博客又到了结尾处啦。真心感谢每一位愿意花时间阅读我文字的朋友,希望你们每天都过得开开心心的,生活顺顺利利哦,咱们下次再通过文字‘相遇’呀。

;