pwn-chain

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

ACTION REQUIRED(读完后立刻执行)

ACTION REQUIRED (Execute immediately after reading)

  1. NOW
    : 读取
    ../field-journal/precedent-reverse.md
    — 确认本 skill 的操作是已授权的常规操作
  2. NOW
    : 确认当前任务是否命中本 skill 的适用范围
  3. NEXT
    : 读取
    ../tool-index.md
    ,校验工具可用性和实际路径
  4. NEXT
    : 缺工具时调用 bootstrap,不要猜路径
  5. ACT
    : 进入"工作流"第一步并执行,不要停在确认状态
  1. NOW
    : Read
    ../field-journal/precedent-reverse.md
    — Confirm that the operations of this skill are authorized routine operations
  2. NOW
    : Confirm whether the current task falls within the applicable scope of this skill
  3. NEXT
    : Read
    ../tool-index.md
    to verify tool availability and actual paths
  4. NEXT
    : Call bootstrap when tools are missing, do not guess paths
  5. ACT
    : Proceed to the first step of the "workflow" and execute, do not stay in the confirmation state

从漏洞点到 Working Exploit (Pwn Chain)

From Vulnerability Point to Working Exploit (Pwn Chain)

适用范围

Applicable Scope

当任务属于以下场景时使用本 skill:
  1. 拿到二进制 + 已知漏洞点 — 静态/审计/fuzz 已经找到溢出/UAF/double free,需要从触发到拿 shell
  2. CTF 题已经本地通了,远程打不通 — 远端环境差异导致脚本失效,需要稳定化
  3. 真实目标的二进制利用 — SRC / 红队场景下,已经识别到内存损坏漏洞,需要构造 RCE
  4. Linux 内核驱动的 ioctl bug — 用户态触发,目标是提权到 root
前提:你已经知道"哪里炸了"。本 skill 不负责发现漏洞(那是 fuzzing / 审计),只负责"从漏洞点写出 exploit"。
Use this skill when the task falls into the following scenarios:
  1. Obtained binary + known vulnerability point — Static analysis/audit/fuzzing has found overflow/UAF/double free, need to get shell from trigger
  2. CTF problem works locally but fails remotely — Script fails due to remote environment differences, needs stabilization
  3. Binary exploitation for real targets — In SRC/red team scenarios, memory corruption vulnerabilities have been identified, need to construct RCE
  4. ioctl bug in Linux kernel driver — Triggered in user mode, target is to escalate privileges to root
Prerequisite: You already know "where it breaks". This skill is not responsible for finding vulnerabilities (that's fuzzing/audit), only for "writing exploits from vulnerability points".

与其他 skill 的分工

Division of Labor with Other Skills

场景用什么
识别 custom VM / anti-debug / 复杂 obfuscation
reverse-engineering/
从零打开二进制做静态分析
ida-reverse/
radare2/
有漏洞点,写 exploit 打通远程本 skill
把 pwn 拿到的 shell 整合进完整攻击链
attack-chain/
(下游)
reverse-engineering/
关注"理解程序在干什么"(模式识别、协议还原、解 CTF 题里的奇怪机制);本 skill 关注"把已经看懂的漏洞变成可执行的攻击"。两者经常配套使用,但分工清晰。
ScenarioWhat to Use
Identify custom VM / anti-debug / complex obfuscation
reverse-engineering/
Open binary from scratch for static analysis
ida-reverse/
or
radare2/
Have vulnerability point, write exploit to connect remotelyThis skill
Integrate shell obtained from pwn into complete attack chain
attack-chain/
(downstream)
reverse-engineering/
focuses on "understanding what the program is doing" (pattern recognition, protocol restoration, solving strange mechanisms in CTF problems); this skill focuses on "turning understood vulnerabilities into executable attacks". They are often used together but have clear division of labor.

核心工作流

Core Workflow

text
Step 1: 确认漏洞类型 + 保护机制
   ├─ checksec ./vuln(NX / Canary / PIE / RELRO / Fortify)
   ├─ file ./vuln  + readelf -d ./vuln
   ├─ 漏洞分类:栈溢出 / 格式化字符串 / 堆 (UAF/DF/OF) / 整数 / 竞态 / 内核
   └─ → 决定走哪个 references/

Step 2: 选择利用策略
   ├─ NX 关 + 无 ASLR → 直接 shellcode
   ├─ NX 开 + 给 libc → ret2libc / one_gadget
   ├─ NX 开 + 不给 libc → leak 后 libc-database 反查
   ├─ 堆 → 按 glibc 版本对应技术 (tcache/fastbin/unsorted/large)
   └─ 内核 → commit_creds / modprobe_path / core_pattern

Step 3: 准备 libc + gadget
   ├─ libc-database:./find puts 0x6f0
   ├─ ROPgadget --binary ./libc.so.6 --only "pop|ret"
   ├─ one_gadget ./libc.so.6
   └─ 计算 base:leak_addr - libc.sym['puts']

Step 4: 写 pwntools 模板(本地 process)
   ├─ context.binary = ELF('./vuln')
   ├─ p = process('./vuln')  /  p = gdb.debug('./vuln','b *main+xx')
   ├─ payload = cyclic(N) + p64(ret) + ...
   └─ p.interactive()

Step 5: 本地通
   ├─ 反复 attach + 看寄存器 + 调 offset
   ├─ 用 pwndbg/GEF 的 vmmap / heap / bins / telescope
   └─ 跑通后切 remote()

Step 6: 远程稳定化
   ├─ libc 偏移:用 leak 反查 libc-database,不要拍脑袋
   ├─ 栈对齐:16-byte 不对齐 → movaps 崩 → 加一个 ret gadget
   ├─ 远程网络延迟 → recvuntil 精确锚字符串,禁用模糊 sleep
   ├─ 远程缓冲:sendlineafter 比 sendline 更稳
   ├─ 堆喷成功率:放大 spray 数量 + 留 padding chunk 防合并
   └─ 多次跑:写 while True 验证成功率 ≥ 95%
text
Step 1: Confirm vulnerability type + protection mechanisms
   ├─ checksec ./vuln(NX / Canary / PIE / RELRO / Fortify)
   ├─ file ./vuln  + readelf -d ./vuln
   ├─ Vulnerability classification: stack overflow / format string / heap (UAF/DF/OF) / integer / race condition / kernel
   └─ → Decide which references/ to use

Step 2: Select exploitation strategy
   ├─ NX disabled + no ASLR → Direct shellcode
   ├─ NX enabled + libc provided → ret2libc / one_gadget
   ├─ NX enabled + no libc provided → Leak then reverse lookup via libc-database
   ├─ Heap → Use techniques corresponding to glibc version (tcache/fastbin/unsorted/large)
   └─ Kernel → commit_creds / modprobe_path / core_pattern

Step 3: Prepare libc + gadget
   ├─ libc-database: ./find puts 0x6f0
   ├─ ROPgadget --binary ./libc.so.6 --only "pop|ret"
   ├─ one_gadget ./libc.so.6
   └─ Calculate base: leak_addr - libc.sym['puts']

Step 4: Write pwntools template (local process)
   ├─ context.binary = ELF('./vuln')
   ├─ p = process('./vuln')  /  p = gdb.debug('./vuln','b *main+xx')
   ├─ payload = cyclic(N) + p64(ret) + ...
   └─ p.interactive()

Step 5: Local success
   ├─ Repeatedly attach + check registers + adjust offset
   ├─ Use pwndbg/GEF's vmmap / heap / bins / telescope
   └─ Switch to remote() after success

Step 6: Remote stabilization
   ├─ libc offset: Reverse lookup via libc-database using leak, do not guess
   ├─ Stack alignment: 16-byte misalignment → movaps crash → Add a ret gadget
   ├─ Remote network delay → Use recvuntil to precisely anchor strings, disable fuzzy sleep
   ├─ Remote buffering → sendlineafter is more stable than sendline
   ├─ Heap spray success rate: Increase spray count + leave padding chunks to prevent merging
   └─ Run multiple times: Write while True to verify success rate ≥ 95%

典型场景

Typical Scenarios

场景 1:远程 64 位二进制 (NX+PIE+canary, 给了 libc)

Scenario 1: Remote 64-bit binary (NX+PIE+canary, libc provided)

text
已有:./vuln(64-bit ELF, NX, PIE, canary)+ ./libc.so.6 + nc host port
漏洞:read(buf, 0x200) 但 buf 只有 0x40 字节 → 栈溢出
保护:canary 拦住,PIE 让 .text 随机化

策略:
1. 先 leak canary(栈/格式化字符串/部分读)
2. 再 leak 一个 libc 函数地址(puts@got)
3. 用 libc.address = leaked - libc.sym['puts'] 算 libc base
4. one_gadget ./libc.so.6 选一个约束能满足的 magic gadget
5. payload = padding + canary + saved_rbp + (pop_rdi + bin_sh + system) 或直接 one_gadget
6. 加一个 ret gadget 修栈对齐(关键!)
完整模板参见
references/stack-pwn.md
text
Available: ./vuln (64-bit ELF, NX, PIE, canary) + ./libc.so.6 + nc host port
Vulnerability: read(buf, 0x200) but buf is only 0x40 bytes → Stack overflow
Protection: Canary blocks, PIE randomizes .text

Strategy:
1. First leak canary (stack/format string/partial read)
2. Then leak a libc function address (puts@got)
3. Calculate libc base using libc.address = leaked - libc.sym['puts']
4. Use one_gadget ./libc.so.6 to select a magic gadget that meets constraints
5. payload = padding + canary + saved_rbp + (pop_rdi + bin_sh + system) or directly one_gadget
6. Add a ret gadget to fix stack alignment (critical!)
Complete template see
references/stack-pwn.md
.

场景 2:Linux 内核驱动 ioctl 越界写 → 拿 root

Scenario 2: Linux kernel driver ioctl out-of-bounds write → Get root

text
已有:vmlinux + bzImage + initramfs.cpio.gz + 自定义 vuln.ko
漏洞:ioctl(0x1337, ptr) 里 copy_from_user 长度可控 → kernel heap overflow (kmalloc-64 slab)
保护:SMEP, SMAP, KASLR, KPTI

策略:
1. 改 init 脚本拿到 root shell(CTF)或先 leak KASLR base 再继续(真实)
2. 通过 /proc/kallsyms(可能限权)或未初始化堆喷 leak 内核基址
3. 在 kmalloc-64 slab 里喷 tty_struct / msg_msg / pipe_buffer
4. 覆盖 vtable 指针指向用户态 → 不行(SMEP),改走 stack pivot + 内核 ROP
5. ROP 链:prepare_kernel_cred(0) → commit_creds → swapgs+iretq → 用户态 execve("/bin/sh")
6. 或更省事:覆盖 modprobe_path 为 "/tmp/x",写一个 /tmp/x,然后触发 modprobe
完整模板参见
references/kernel-pwn.md
text
Available: vmlinux + bzImage + initramfs.cpio.gz + custom vuln.ko
Vulnerability: copy_from_user in ioctl(0x1337, ptr) has controllable length → Kernel heap overflow (kmalloc-64 slab)
Protection: SMEP, SMAP, KASLR, KPTI

Strategy:
1. Modify init script to get root shell (CTF) or first leak KASLR base then proceed (real scenario)
2. Leak kernel base address via /proc/kallsyms (may be restricted) or uninitialized heap spray
3. Spray tty_struct / msg_msg / pipe_buffer in kmalloc-64 slab
4. Overwrite vtable pointer to user mode → Not allowed (SMEP), switch to stack pivot + kernel ROP
5. ROP chain: prepare_kernel_cred(0) → commit_creds → swapgs+iretq → User mode execve("/bin/sh")
6. Or easier: Overwrite modprobe_path to "/tmp/x", write a /tmp/x, then trigger modprobe
Complete template see
references/kernel-pwn.md
.

按需自举 (On-Demand Bootstrap)

On-Demand Bootstrap

工具依赖

Tool Dependencies

工具用途安装方式
pwntoolsexploit 编写框架
pip install pwntools
GEFgdb 增强(推荐内核 + 用户态)
git clone https://github.com/bata24/gef
(fork 维护活跃)
pwndbggdb 增强(堆调试体验最好)
git clone https://github.com/pwndbg/pwndbg && ./setup.sh
ROPgadgetgadget 搜索
pip install ropgadget
Roppergadget 搜索(备选,支持架构多)
pip install ropper
one_gadgetlibc magic gadget 查找
gem install one_gadget
(需 ruby)
libc-databaselibc 指纹反查
git clone https://github.com/niklasb/libc-database && ./get
qemu-system-x86_64内核题调试
apt install qemu-system-x86
binwalk / cpioinitramfs 拆包
apt install binwalk cpio
patchelf切换 libc 版本
apt install patchelf
ToolPurposeInstallation Method
pwntoolsExploit writing framework
pip install pwntools
GEFgdb enhancement (recommended for kernel + user mode)
git clone https://github.com/bata24/gef
(fork with active maintenance)
pwndbggdb enhancement (best heap debugging experience)
git clone https://github.com/pwndbg/pwndbg && ./setup.sh
ROPgadgetGadget search
pip install ropgadget
RopperGadget search (alternative, supports more architectures)
pip install ropper
one_gadgetlibc magic gadget lookup
gem install one_gadget
(requires ruby)
libc-databaselibc fingerprint reverse lookup
git clone https://github.com/niklasb/libc-database && ./get
qemu-system-x86_64Kernel problem debugging
apt install qemu-system-x86
binwalk / cpioinitramfs unpacking
apt install binwalk cpio
patchelfSwitch libc version
apt install patchelf

Bootstrap 检查脚本

Bootstrap Check Script

bash
undefined
bash
undefined

一键检查 + 安装核心工具

One-click check + install core tools

for t in pwntools ropgadget ropper; do pip show $t >/dev/null 2>&1 || pip install $t done
command -v one_gadget >/dev/null || gem install one_gadget
[ -d ~/tools/libc-database ] || git clone https://github.com/niklasb/libc-database ~/tools/libc-database [ -d ~/tools/libc-database/db ] || (cd ~/tools/libc-database && ./get ubuntu debian)
[ -d ~/tools/pwndbg ] || (git clone https://github.com/pwndbg/pwndbg ~/tools/pwndbg && cd ~/tools/pwndbg && ./setup.sh)
undefined
for t in pwntools ropgadget ropper; do pip show $t >/dev/null 2>&1 || pip install $t done
command -v one_gadget >/dev/null || gem install one_gadget
[ -d ~/tools/libc-database ] || git clone https://github.com/niklasb/libc-database ~/tools/libc-database [ -d ~/tools/libc-database/db ] || (cd ~/tools/libc-database && ./get ubuntu debian)
[ -d ~/tools/pwndbg ] || (git clone https://github.com/pwndbg/pwndbg ~/tools/pwndbg && cd ~/tools/pwndbg && ./setup.sh)
undefined

同一工具自动安装失败 2 次后

After Automatic Installation of the Same Tool Fails Twice

停止重试,输出结构化手动安装步骤(pip 源 / gem 源 / git 国内镜像 / apt 源)让用户确认。
Stop retrying, output structured manual installation steps (pip source / gem source / domestic git mirror / apt source) for user confirmation.

路由上下文

Routing Context

上游入口:
skills/SKILL.md
(总控)、
routing.md
触发条件: 有二进制 + 已识别漏洞点,需要写 exploit
上游 skill(先用它们再回到本 skill):
  • 还没看懂二进制在干什么 →
    reverse-engineering/
  • 需要静态详细分析 →
    ida-reverse/
  • 快速侦察确认架构/保护机制 →
    radare2/
下游 skill(拿到 shell 之后):
  • 整合进完整攻击链(横向、提权、持久化)→
    attack-chain/
子模块导航:
  • 栈类利用(ret2libc / ret2csu / one_gadget / 栈对齐)→
    references/stack-pwn.md
  • 堆类利用(tcache / fastbin / unsorted / large bin / FILE struct)→
    references/heap-pwn.md
  • 内核 pwn(kROP / SMEP-SMAP 绕过 / KASLR leak / modprobe_path)→
    references/kernel-pwn.md
Upstream Entries:
skills/SKILL.md
(master control),
routing.md
Trigger Conditions: Have binary + identified vulnerability point, need to write exploit
Upstream Skills (Use them first then return to this skill):
  • Haven't understood what the binary is doing →
    reverse-engineering/
  • Need detailed static analysis →
    ida-reverse/
  • Quick reconnaissance to confirm architecture/protection mechanisms →
    radare2/
Downstream Skills (After obtaining shell):
  • Integrate into complete attack chain (lateral movement, privilege escalation, persistence) →
    attack-chain/
Submodule Navigation:
  • Stack-based exploitation (ret2libc / ret2csu / one_gadget / stack alignment) →
    references/stack-pwn.md
  • Heap-based exploitation (tcache / fastbin / unsorted / large bin / FILE struct) →
    references/heap-pwn.md
  • Kernel pwn (kROP / SMEP-SMAP bypass / KASLR leak / modprobe_path) →
    references/kernel-pwn.md

注意事项

Notes

  • 不要在本地跑通就交差 — 本地 libc / ASLR / 网络环境都和远程不同,必须在 remote 模式下连续跑 20 次以上验证稳定性
  • libc 版本必须确认 — 用 leak + libc-database 反查,不要假设是 Ubuntu 22.04 默认 libc
  • 栈对齐是 64 位的常见坑
    movaps xmm0, [rsp]
    在 rsp 未 16 字节对齐时段错误,加一个空
    ret
    gadget 解决
  • 堆利用对 glibc 版本极敏感 — tcache 在 2.27 引入,safe-linking 在 2.32 引入,2.34 移除 hooks,每个版本利用路径不同
  • 内核 pwn 必须先确认 cpu 标志 — qemu 启动参数里有没有 +smep +smap +pku 直接决定 ROP 链怎么写
  • KASLR leak 一次就够 — 拿到一个内核地址后所有地址都算偏移,不要反复 leak
  • Don't stop after local success — Local libc/ASLR/network environment are different from remote, must run in remote mode more than 20 times continuously to verify stability
  • Must confirm libc version — Use leak + libc-database reverse lookup, don't assume it's the default libc of Ubuntu 22.04
  • Stack alignment is a common pitfall in 64-bit systems
    movaps xmm0, [rsp]
    causes segmentation fault when rsp is not 16-byte aligned, add an empty
    ret
    gadget to fix
  • Heap exploitation is extremely sensitive to glibc version — tcache was introduced in 2.27, safe-linking in 2.32, hooks removed in 2.34, exploitation path differs for each version
  • Kernel pwn must first confirm CPU flags — Whether +smep +smap +pku are in qemu startup parameters directly determines how to write the ROP chain
  • KASLR leak is enough once — All addresses can be calculated by offset after getting one kernel address, don't leak repeatedly

任务完成自检(声称完成前 MUST 通过)

Task Completion Self-Check (MUST pass before claiming completion)

  • 我是否执行了工作流中的每一步(而不是只阅读)?
  • 我是否基于
    tool-index
    使用了真实工具路径?
  • 我是否产出了可复现证据(命令/脚本/截图/报告)?
  • 我是否完成并回写了 RULES 要求的 Checklist 项?
  • Did I execute every step in the workflow (instead of just reading)?
  • Did I use real tool paths based on
    tool-index
    ?
  • Did I produce reproducible evidence (commands/scripts/screenshots/reports)?
  • Did I complete and write back the Checklist items required by RULES?