CTF-pwn 技术总结(3)
字数 3032 2025-08-07 08:22:15
Linux PWN 安全机制与绕过技术详解
一、Linux 安全机制概述
Linux 系统提供了多种安全机制来防止漏洞利用,理解这些机制及其绕过方法是 CTF PWN 比赛的基础。主要安全机制包括:
- NX (No-eXecute)
- ASLR (Address Space Layout Randomization)
- Stack Canary
- RELRO (Relocation Read-Only)
- PIE (Position Independent Executable)
- FORTIFY_SOURCE
- Seccomp
二、NX (No-eXecute) 保护机制
基本原理
- 将数据区域(如栈和堆)标记为不可执行
- 防止攻击者在栈或堆上执行shellcode
- 通过ELF程序的PT_GNU_STACK段或内核的NX位实现
检查方法
checksec --file=target
查看输出中的"NX enabled"字段
绕过技术
1. ROP (Return Oriented Programming)
- 利用程序中已有的代码片段(gadgets)构造攻击链
- 每个gadget以ret指令结尾
- 通过连续调用多个gadgets实现攻击目标
2. Ret2Libc
- 返回到libc中的函数(如system、execve)
- 需要泄露libc地址(当ASLR开启时)
- 典型步骤:
- 泄露libc函数地址
- 计算libc基址
- 构造system("/bin/sh")调用
3. JIT Spraying
- 在可执行内存区域(如JIT编译区域)注入代码
- 适用于浏览器等支持JIT的应用
4. mprotect
- 使用mprotect修改内存页属性为可执行
- 需要先泄露地址信息
三、ASLR (Address Space Layout Randomization)
基本原理
- 随机化内存布局(栈、堆、库等地址)
- 内核参数
/proc/sys/kernel/randomize_va_space控制:- 0:关闭ASLR
- 1:栈、库随机化
- 2:栈、库、堆随机化
检查方法
cat /proc/sys/kernel/randomize_va_space
绕过技术
1. 信息泄露
- 通过格式化字符串、UAF等漏洞泄露地址
- 计算基址偏移
- 典型目标:
- 泄露libc地址计算libc基址
- 泄露程序地址计算程序基址(PIE情况下)
2. 暴力破解
- 适用于32位系统(地址空间小)
- 对可能的地址进行尝试
3. Return-to-plt
- 在PIE未开启时使用
- PLT地址固定,可直接调用
4. 部分覆盖
- 在已知部分地址的情况下(如栈地址后12位固定)
- 覆盖地址的低字节
四、Stack Canary
基本原理
- 在栈帧的返回地址前放置随机值(canary)
- 函数返回前检查canary是否被修改
- 三种类型:
- Terminator canary(含终止字符)
- Random canary(完全随机)
- Random XOR canary(与部分控制数据异或)
检查方法
checksec --file=target
查看输出中的"Canary found"字段
绕过技术
1. 泄露Canary
- 通过格式化字符串漏洞泄露
- 通过缓冲区溢出部分覆盖泄露(逐字节爆破)
- 通过侧信道攻击获取
2. 劫持__stack_chk_fail
- 修改GOT表中__stack_chk_fail的地址
- 需要能够写GOT表(RELRO partial或关闭)
3. 不触发Canary检查
- 覆盖SEH链(Windows)
- 覆盖其他关键数据而非返回地址
4. 多线程爆破
- 在多线程程序中,子线程的canary可能与主线程相同
- 通过子线程泄露主线程canary
五、RELRO (Relocation Read-Only)
基本原理
- 控制ELF重定位区域的读写权限
- 两种级别:
- Partial RELRO(部分保护)
- GOT表可写
- 重定位段只读
- Full RELRO(完全保护)
- 所有重定位区域只读
- GOT表变为PLT的一部分且只读
- Partial RELRO(部分保护)
检查方法
checksec --file=target
查看输出中的"RELRO"字段
绕过技术
1. Partial RELRO
- 可修改GOT表
- 技术:
- GOT表劫持
- 修改free@got为system等
2. Full RELRO
- 无法直接修改GOT表
- 替代方法:
- 使用ROP
- 使用其他可写区域(如.dynamic)
- 利用FILE结构体攻击
六、PIE (Position Independent Executable)
基本原理
- 程序代码段地址随机化
- 类似ASLR,但作用于主程序而非共享库
- 所有地址为相对偏移
检查方法
checksec --file=target
查看输出中的"PIE enabled"字段
绕过技术
1. 信息泄露
- 泄露程序地址计算基址
- 常见泄露点:
- 栈地址
- 堆地址
- 已知指针内容
2. 部分覆盖
- 在已知部分地址的情况下
- 覆盖指针的低位字节
3. 非PIE段利用
- 利用程序中的非PIE段(如.data、.bss)
- 如果存在固定地址的可写区域
七、FORTIFY_SOURCE
基本原理
- 编译时对危险函数(如memcpy、strcpy)添加检查
- 检查缓冲区大小是否足够
- 需要-O2优化和定义_FORTIFY_SOURCE
检查方法
nm -D target | grep _chk
绕过技术
1. 不使用受保护函数
- 寻找未受保护的替代函数
- 如使用read代替strcpy
2. 精确控制长度
- 确保缓冲区大小"看似"足够
- 避免触发长度检查
3. 其他漏洞组合
- 结合其他类型漏洞绕过
- 如格式化字符串、UAF等
八、Seccomp
基本原理
- Linux内核的沙箱机制
- 限制进程可用的系统调用
- 常见于CTF的pwn题目中
检查方法
seccomp-tools dump ./target
绕过技术
1. 允许的系统调用
- 分析允许的系统调用
- 组合可用系统调用完成攻击
- 如仅允许open/read/write时构造ORW(Open-Read-Write)链
2. 文件描述符重用
- 重用已打开的文件描述符
- 避免需要受限的系统调用
3. 信号处理
- 通过信号处理机制绕过
- 如sigreturn-oriented programming (SROP)
4. 内核漏洞
- 利用内核漏洞突破限制
- 需要题目环境存在内核漏洞
九、综合绕过示例
场景:64位程序,开启NX、ASLR、Canary、PIE
攻击步骤:
-
泄露Canary:
- 通过格式化字符串或缓冲区溢出部分覆盖泄露
payload = b'A' * (canary_offset) # 填满到canary前 p.send(payload) p.recvuntil(payload) canary = u64(b'\x00' + p.recv(7)) # canary第一个字节通常是\x00 -
泄露程序地址:
- 通过GOT表泄露函数地址计算PIE基址
puts_got = elf.got['puts'] payload = flat([ b'A' * canary_offset, canary, b'B' * 8, # 覆盖rbp pop_rdi, puts_got, elf.plt['puts'], elf.sym['main'] # 返回main重新利用 ]) p.send(payload) puts_addr = u64(p.recvline()[:-1].ljust(8, b'\x00')) libc.address = puts_addr - libc.sym['puts'] -
构造ROP链:
- 使用泄露的地址构造system("/bin/sh")
binsh = next(libc.search(b'/bin/sh')) system = libc.sym['system'] payload = flat([ b'A' * canary_offset, canary, b'B' * 8, pop_rdi, binsh, system ])
十、防护检测与调试技巧
1. 检查程序保护
checksec --file=target
readelf -l target | grep GNU_STACK # 检查NX
readelf -d target | grep RELRO # 检查RELRO级别
2. 调试技巧
- GDB插件:
- pwndbg:
canary命令查看canary - gef:
checksec命令检查保护
- pwndbg:
- ASLR临时关闭:
setarch `uname -m` -R /bin/bash - 查看内存映射:
cat /proc/$(pidof target)/maps
十一、总结与练习建议
1. 学习路线建议
- 从无保护程序开始练习
- 逐步增加保护机制:
- 先NX → 然后ASLR → 接着Canary → 最后PIE+Full RELRO
- 掌握信息泄露技巧
- 熟练ROP构造
2. 常见题目类型
- 栈溢出 + NX → Ret2Libc/ROP
- 栈溢出 + Canary → 泄露Canary
- PIE程序 → 泄露程序地址
- 堆题目 → 结合堆利用技巧
3. 必备工具
- pwntools
- ROPgadget/ropper
- one_gadget
- seccomp-tools
- checksec
通过系统学习这些保护机制及其绕过方法,可以逐步提高CTF PWN的解题能力。建议在实际题目中反复练习每种技术的应用。