Pwn 课程第七节: 格式化字符串漏洞

1. 格式化字符串漏洞概述

格式化字符串漏洞(Format String Vulnerability)是由于程序直接使用用户输入作为格式化参数,导致攻击者可以泄露内存信息或修改程序数据。

1.1 格式化字符串的原理

在 C 语言中,printfsprintffprintf 等函数用于格式化输出。例如:

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 修改返回地址

  1. 找到 printf 的 GOT 地址:

    objdump -R ./vuln_fmt | grep printf
  2. 构造输入,使 printf 的 GOT 指向 system(),劫持执行 /bin/sh

5. 练习题

  1. 使用 gdb 观察 printf("%x %x %x %x") 的输出,理解栈布局。

  2. 使用 %n 修改内存值,使程序行为发生变化。

  3. 研究 GOT 劫持技术,并尝试利用格式化字符串漏洞执行 system("/bin/sh")

6. 总结

  • 了解格式化字符串的工作原理。

  • 通过 %x%p 泄露内存信息。

  • 通过 %n 进行内存修改。

  • 了解 GOT 劫持的利用方式。

### 格式化字符串漏洞 PWN 的利用与防御 #### 漏洞原理概述 格式化字符串漏洞源于程序未正确验证输入参数,允许攻击者通过控制传递给 `printf` 或其他格式化函数的参数来访问或修改内存中的数据[^1]。 #### 利用方式分析 1. **获取敏感信息** 攻击者可以通过格式化字符串漏洞读取堆栈上的内容,进而泄露程序内部状态或其他重要信息。例如,使用 `%x` 系列占位符可以逐字节打印堆栈中的值[^2]。 2. **覆盖目标地址** 借助特殊格式化字符(如 `%n`),攻击者能够实现对指定内存位置的写操作。具体而言,当程序调用了类似 `printf(user_input)` 而不加任何过滤时,恶意构造的输入可定位到特定变量并更改其数值[^3]。 3. **绕过保护机制** 在某些情况下,即使启用了现代防护技术(如 ASLR 地址空间布局随机化),如果存在此类型的缺陷,则仍可能被用来计算实际加载基址从而突破限制。比如通过泄漏 libc 库中某个已知偏移量对应的绝对地址反推出整个库映射范围[^4]。 #### 防护策略建议 为了有效防范上述风险,可以从以下几个方面着手: 1. **严格校验用户输入** - 对所有来自外部的数据都应进行全面检查,在将其作为格式说明符传入前确认合法性。 - 使用更安全版本的标准 I/O 函数替代原始形式;例如采用带长度限定参数的方法代替传统无界接口。 2. **启用编译器优化选项** - GCC 提供了专门针对此类问题的支持功能——开启 `-Wformat-nonliteral` 和 `-D_FORTIFY_SOURCE=2` 编译标志可以帮助检测潜在隐患,并阻止运行期非法行为发生。 3. **隔离关键资源管理逻辑** - 将涉及敏感操作的部分单独封装起来并与其余部分保持距离,减少暴露面的同时也便于集中精力加强这部分的安全保障级别。 ```python def safe_printf(format_string, *args): try: formatted_output = format_string % args # Safe usage with explicit arguments. print(formatted_output) except TypeError as e: print(f"Error occurred while formatting string: {e}") safe_printf("%s is %d years old.", "Alice", 25) ``` 以上代码片段展示了如何以一种较为稳妥的方式运用 Python 中类似的字符串插值特性,避免直接拼接未经审查的内容进入最终呈现层。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值