binary-exploitation-methodology
$
npx mdskill add wgpsec/AboutSecurity/binary-exploitation-methodologyAnalyze binary vulnerabilities and select exploitation strategies.
- Identify stack, heap, format string, and use-after-free flaws.
- Evaluate ASLR, NX, canary, PIE, and RELRO protections.
- Choose between ret2win, ret2shellcode, ROP, and ret2libc approaches.
- Generate exploit code using GDB and pwntools for testing.
SKILL.md
.github/skills/binary-exploitation-methodologyView on GitHub ↗
---
name: binary-exploitation-methodology
description: "二进制漏洞利用基础方法论。涵盖漏洞识别(栈溢出/堆溢出/格式化字符串/UAF)、保护机制分析(ASLR/NX/Stack Canary/PIE/RELRO)、利用策略选择(ret2win/ret2shellcode/ROP/ret2libc)、调试与利用开发流程。当 Agent 需要分析二进制程序漏洞、选择利用策略、或理解保护机制绕过方法时触发。区别于 CTF pwn 技巧,侧重实战方法论。"
metadata:
tags: "二进制利用,栈溢出,rop,保护机制,gdb,pwntools,实战"
category: "exploit/binary"
---
# 二进制漏洞利用基础方法论
> **核心流程**:分析目标二进制 → 识别保护机制 → 判断漏洞类型 → 选择利用策略 → 开发利用代码 → 测试验证
## 深入参考
- 利用策略完整决策树与保护机制绕过详解 → [references/exploitation-strategy-reference.md](references/exploitation-strategy-reference.md)
- Heap 利用实战方法论(tcache/fastbin/unsorted bin/House of X) → [references/heap-exploitation.md](references/heap-exploitation.md)
- Format string 完整攻击流程 → [references/format-string-exploitation.md](references/format-string-exploitation.md)
- libc 版本识别与偏移计算 → [references/libc-identification.md](references/libc-identification.md)
- seccomp 沙箱评估与绕过 → [references/seccomp-sandbox-assessment.md](references/seccomp-sandbox-assessment.md)
---
## Phase 1: 目标分析
```
目标二进制初步分析:
├─ 文件类型与架构
│ ├─ file <binary>
│ ├─ ELF 32/64-bit, LSB/MSB
│ └─ 架构: x86, x86_64, ARM, MIPS
├─ 链接方式
│ ├─ 动态链接 → 有 libc, GOT/PLT 可利用
│ └─ 静态链接 → 无外部库,gadget 丰富但无 libc 函数地址泄露
├─ 符号信息
│ ├─ stripped → 需要逆向分析函数
│ └─ not stripped → 函数名可见,分析更容易
└─ 基本字符串搜索
└─ strings <binary> | grep -i "flag\|shell\|bin/sh\|password"
```
### 初步分析命令
```bash
# 文件类型与架构
file ./target_binary
# 检查动态链接库
ldd ./target_binary
# 符号表
nm ./target_binary 2>/dev/null | head -30
# 有价值的字符串
strings ./target_binary | grep -i "flag\|shell\|/bin/sh\|system\|exec"
# 反汇编关键函数
objdump -d -Mintel ./target_binary | less
```
## Phase 2: 保护机制识别
```
保护机制检查决策树:
├─ checksec --file=<binary>
├─ CANARY(Stack Canary / 栈金丝雀)
│ ├─ 启用 → 需要泄露 canary 值才能覆盖返回地址
│ │ ├─ 格式化字符串泄露
│ │ ├─ 信息泄露漏洞
│ │ └─ brute force(仅 fork 模式有效)
│ └─ 未启用 → 可直接覆盖返回地址
├─ NX(No-Execute / 不可执行)
│ ├─ 启用 → 栈上 shellcode 不可执行,需用 ROP/ret2libc
│ └─ 未启用 → 可在栈上放置 shellcode 并跳转执行
├─ PIE(Position Independent Executable)
│ ├─ 启用 → 代码段地址随机化,需要泄露基地址
│ │ ├─ partial overwrite(只改低位字节)
│ │ └─ 信息泄露获取代码段地址
│ └─ 未启用 → 代码段地址固定,可直接使用 gadget 地址
├─ ASLR(地址空间布局随机化)
│ ├─ 启用 → 栈/堆/libc 地址随机
│ │ ├─ 信息泄露获取 libc 基地址
│ │ ├─ ret2plt 间接调用
│ │ ├─ ret2dlresolve 动态解析
│ │ └─ brute force(32-bit 熵较低)
│ └─ 未启用 → 地址可预测
├─ RELRO(Relocation Read-Only)
│ ├─ Full RELRO → GOT 只读,不可覆写 GOT 条目
│ ├─ Partial RELRO → GOT 可写,可覆写 GOT 实现任意调用
│ └─ No RELRO → .dynamic 也可写
└─ Fortify Source
└─ 编译时替换不安全函数为安全版本
```
### 检查命令
```bash
# 一键检查所有保护
checksec --file=./target_binary
# 手动检查 NX
readelf -l ./target_binary | grep GNU_STACK
# RW 表示 NX 启用(栈不可执行),RWE 表示栈可执行
# 检查 PIE
readelf -h ./target_binary | grep Type
# DYN 表示 PIE,EXEC 表示非 PIE
# 检查 ASLR(系统级)
cat /proc/sys/kernel/randomize_va_space
# 0=关闭, 1=部分, 2=完全
# 检查 RELRO
readelf -l ./target_binary | grep GNU_RELRO
readelf -d ./target_binary | grep BIND_NOW
```
## Phase 3: 漏洞类型判断
```
漏洞类型识别决策树:
├─ 栈溢出(Stack Buffer Overflow)
│ ├─ 特征: gets/strcpy/sprintf/scanf 等不安全函数
│ ├─ 可覆盖: 返回地址、保存的寄存器、局部变量
│ └─ 子类型
│ ├─ 标准溢出 → 覆盖返回地址
│ ├─ Off-by-one → 只能覆盖 1 字节(通常是 EBP 低字节)
│ └─ 整数溢出导致的栈溢出
├─ 格式化字符串(Format String)
│ ├─ 特征: printf(user_input) 而非 printf("%s", user_input)
│ ├─ 能力: 任意读 + 任意写
│ └─ 利用: %p 泄露栈内容, %n 写入任意地址
├─ 堆溢出(Heap Overflow)
│ ├─ 特征: malloc 后写入超出分配大小
│ ├─ 利用: 覆盖堆元数据或相邻 chunk 的数据
│ └─ 进阶: fastbin attack, tcache poisoning, unsafe unlink
├─ Use-After-Free (UAF)
│ ├─ 特征: free 后指针未置空且继续使用
│ ├─ 利用: 重新分配同大小 chunk 控制已释放内存
│ └─ 通常需要理解对象布局
├─ 数组越界(Array Out-of-Bounds)
│ ├─ 特征: 可控的数组索引缺少边界检查
│ └─ 利用: 任意读/写
└─ 整数溢出
├─ 特征: 大小计算中的整数截断/回绕
└─ 通常作为触发其他漏洞的前置条件
```
### 漏洞定位方法
```bash
# 搜索不安全函数
objdump -d ./target_binary | grep -E "gets|strcpy|sprintf|scanf|strcat"
# Ghidra 中搜索(使用反编译视图)
# Search → For Strings → "system" / "/bin/sh"
# 查找 cross-reference 到危险函数的路径
# 动态 fuzzing
# 简单输入测试
python3 -c "print('A'*200)" | ./target_binary
python3 -c "print('A'*500)" | ./target_binary
# 段错误 → 可能存在溢出
```
## Phase 4: 利用策略选择
```
利用策略总决策树:
目标: 调用已有函数(ret2win)
├─ 无 PIE + 无 Canary → 直接覆盖返回地址为 win 函数地址
├─ 有 PIE → 先泄露基地址或 partial overwrite
├─ 有 Canary → 先泄露 canary
├─ 需要设置参数
│ ├─ ROP gadgets 充足 → ROP chain 设置寄存器
│ ├─ SROP → sigreturn 控制所有寄存器
│ └─ ret2csu / ret2vdso → 控制多个寄存器
└─ WWW (Write-What-Where) → 通过任意写调用 win 函数
目标: 获取 Shell (RCE)
├─ NX 未启用
│ ├─ 无 ASLR → ret2shellcode(跳转到栈上 shellcode)
│ ├─ 有 ASLR → ret2esp / ret2reg(通过 gadget 跳转到 shellcode)
│ └─ 有 NX → ROP 调用 mprotect 使栈可执行,再跳转 shellcode
├─ 通过 syscall
│ ├─ ret2syscall → ROP chain 调用 execve("/bin/sh", 0, 0)
│ └─ SROP → sigreturn 设置寄存器后 syscall
├─ 通过 libc
│ ├─ 静态链接 + 无 PIE → system 和 "/bin/sh" 地址固定
│ ├─ 无 ASLR → libc 地址固定,直接 ret2libc
│ ├─ 有 ASLR + 无 PIE + binary 有 system → ret2plt(system)
│ ├─ 有 ASLR + 无 PIE + binary 无 system
│ │ ├─ ret2dlresolve → 动态解析 system 地址
│ │ └─ 泄露 libc 地址 → 计算 system 偏移
│ └─ 有 ASLR + 有 PIE + 未知 libc
│ ├─ 先绕过 PIE(泄露代码段地址)
│ ├─ 泄露 libc 函数地址 → 确定 libc 版本
│ └─ 计算 system 和 "/bin/sh" 地址
└─ Stack Pivoting
├─ Off-by-one → 控制 EBP → 控制 ESP → 控制 RET
└─ 构造 payload 到可控内存,通过 EBP 跳转
```
### 保持循环利用(Eternal Loop)
```
单次漏洞触发不够时,需要多次利用:
├─ ROP chain 中跳回 main 或漏洞函数地址
├─ 覆写 GOT 中 exit 条目 → 跳回漏洞点
└─ .fini_array 写入两个函数:
├─ 函数 1: 调用漏洞函数
└─ 函数 2: 调用 __libc_csu_fini(再次触发 .fini_array)
```
## Phase 5: 利用开发
### 确定溢出偏移量
```bash
# 使用 pwntools 生成 cyclic pattern
python3 -c "from pwn import *; print(cyclic(300))" | ./target_binary
# GDB 中确定偏移
# (gdb) run < <(python3 -c "from pwn import *; print(cyclic(300))")
# (gdb) x/wx $rsp → 查看覆盖到返回地址的值
# python3 -c "from pwn import *; print(cyclic_find(0x61616168))"
# 或使用 Metasploit
msf-pattern_create -l 300
msf-pattern_offset -l 300 -q <value>
```
### pwntools 利用模板
```python
from pwn import *
# 设置上下文
context.binary = elf = ELF('./target_binary')
context.log_level = 'debug'
# 本地 / 远程
# p = process('./target_binary')
# p = remote('host', port)
# 构造 payload
offset = 72 # 根据实际偏移调整
payload = b'A' * offset
# ret2win 示例
payload += p64(elf.symbols['win_function'])
# ret2libc 示例(需要先泄露 libc 基地址)
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
# libc_base = leaked_addr - libc.symbols['puts']
# system = libc_base + libc.symbols['system']
# bin_sh = libc_base + next(libc.search(b'/bin/sh'))
# ret = elf address of a "ret" gadget (stack alignment)
# payload += p64(ret) + p64(pop_rdi) + p64(bin_sh) + p64(system)
p = process('./target_binary')
p.sendline(payload)
p.interactive()
```
### ROP Chain 构造
```bash
# 搜索 gadgets
ROPgadget --binary ./target_binary | grep "pop rdi"
ROPgadget --binary ./target_binary | grep "pop rsi"
ropper --file ./target_binary --search "pop rdi"
# one_gadget(libc 中的一键 shell gadget)
one_gadget /lib/x86_64-linux-gnu/libc.so.6
```
## Phase 6: 测试验证
```
验证流程:
├─ 本地测试
│ ├─ 关闭 ASLR 测试: echo 0 > /proc/sys/kernel/randomize_va_space
│ ├─ 确认 exploit 可靠触发
│ └─ 开启 ASLR 测试稳定性
├─ 调试失败排查
│ ├─ 栈对齐问题(x86_64 要求 16 字节对齐)
│ │ └─ 在 payload 中加一个 ret gadget 对齐栈
│ ├─ 坏字符(\x00, \x0a, \x0d)
│ │ └─ 检查输入函数是否截断特定字符
│ ├─ 地址计算错误
│ │ └─ GDB 中 verify: x/gx $rsp, info registers
│ └─ 远程环境差异
│ ├─ libc 版本不同
│ ├─ 栈偏移不同
│ └─ 使用 pwntools 的 DynELF 动态泄露
├─ 远程验证
│ ├─ 调整 payload 适配远程环境
│ └─ 处理网络延迟与 IO 缓冲
└─ 可靠性测试
└─ 多次运行确认成功率
```
### GDB 调试技巧
```bash
# 确保 GDB 与实际运行地址一致
# (gdb) unset env LINES
# (gdb) unset env COLUMNS
# (gdb) set env _=/full/path/to/binary
# 查看崩溃时寄存器状态
# (gdb) info registers
# (gdb) x/20gx $rsp
# (gdb) bt
# 静态链接二进制的 backtrace 定位输入点
# 运行程序 → 等待输入 → Ctrl+C → bt
```
## 工具速查
| 工具 | 用途 |
|------|------|
| checksec | 检查二进制保护机制 |
| pwntools | 利用开发框架 |
| GDB + GEF/pwndbg | 调试分析 |
| ROPgadget | ROP gadget 搜索 |
| one_gadget | libc 中一键 shell gadget |
| Ghidra | 反编译与逆向 |
| ropper | gadget 搜索与 ROP chain 生成 |
| msf-pattern_create | 偏移量计算 |
| readelf / objdump | 二进制信息查看 |
More from wgpsec/AboutSecurity
- 401-403-bypass401/403 访问拒绝绕过方法论。当遇到管理后台、API 端点返回 401/403 Forbidden 时使用。覆盖路径操纵、HTTP 方法篡改、Header 注入、协议降级、组合攻击
- ad-acl-abuseActive Directory ACL 滥用攻击方法论。当 BloodHound 发现 GenericAll/WriteDACL/WriteOwner/GenericWrite/ForceChangePassword 等危险 ACE 时使用。覆盖 ACE 枚举、权限滥用链、Shadow Credentials、RBCD 攻击
- ad-delegation-attackKerberos 委派攻击(非约束/约束/RBCD)。当 BloodHound 发现委派配置、或已获取有 SPN 的服务账号/机器账号控制权时使用。通过 S4U 协议滥用可实现跨服务模拟任意用户,常用于域内权限提升和横向移动。
- ad-domain-attackActive Directory 域环境攻击全链路。当目标主机在域环境中(systeminfo 显示 Domain 非 WORKGROUP)、发现 88/389/636 端口、或获取到域用户凭据时使用。覆盖域信息收集、用户枚举、Kerberoasting、AS-REP Roasting、委派攻击、ACL 滥用、DCSync、Golden/Silver Ticket
- ad-persistenceAD 域环境持久化技术。当已获取域管/本地管理员权限、需要建立持久访问以确保重启或密码更改后仍能回到目标环境时使用。覆盖主机级持久化(计划任务/注册表Run/COM劫持/WMI事件订阅/Windows服务/启动文件夹)、域级持久化(Golden Ticket/Silver Ticket/Skeleton Key/DSRM/AdminSDHolder)、DCShadow/GoldenGMSA高级技术、清理命令与检测规避
- ad-trust-attack域信任关系攻击。当目标存在多域/多林环境时使用。包含父子域提权(Golden Ticket + ExtraSid)、跨林攻击(SID History/MSSQL Trust Links)、单向信任利用。已获取子域 Domain Admin 或发现信任关系时优先加载。
- adcs-certipy-attackActive Directory Certificate Services (ADCS) 证书攻击。当发现域内有 CA 服务器、ADCS Web Enrollment、证书模板配置错误时使用。覆盖 ESC1-ESC11 所有证书滥用路径、Certipy 工具链、证书伪造、NTLM 中继到 ADCS。发现 ADCS/CA/证书/certsrv 相关内容时一定要使用此技能
- adinfo-enum使用 Adinfo 进行 Active Directory 信息收集。当获得域用户凭据后需要快速收集域环境信息时使用。Adinfo 是一个快速 AD 信息收集工具,一条命令输出域控列表、域管用户、信任关系、GPO、SPN、委派配置等关键信息——比手动 LDAP 查询快得多。发现域环境后第一步信息收集使用此技能
- agent-security|
- ai-data-security|