ctf-pwn

ctf-pwn

热门

提供CTF挑战中的二进制利用技术。当你已经有一个脆弱的本地目标或服务,需要将内存损坏或底层原语转化为代码执行或权限提升时使用,例如缓冲区溢出、格式化字符串、堆漏洞、ROP、ret2libc、shellcode、内核利用、seccomp绕过、沙箱逃逸或Windows/Linux利用链。当主要障碍是理解二进制文件的功能时不要使用,应首先进行逆向工程。不要用于纯Web漏洞、磁盘或数据包取证、或独立的密码学/数学挑战。

2723Star
328Fork
更新于 2026/7/10
SKILL.md
readonly只读
name
ctf-pwn
description

提供CTF挑战中的二进制利用技术。当你已经有一个脆弱的本地目标或服务,需要将内存损坏或底层原语转化为代码执行或权限提升时使用,例如缓冲区溢出、格式化字符串、堆漏洞、ROP、ret2libc、shellcode、内核利用、seccomp绕过、沙箱逃逸或Windows/Linux利用链。当主要障碍是理解二进制文件的功能时不要使用,应首先进行逆向工程。不要用于纯Web漏洞、磁盘或数据包取证、或独立的密码学/数学挑战。

CTF 二进制利用(Pwn)

二进制利用(Pwn)CTF挑战的快速参考。每种技术在此有一行说明;详细信息请参见支持文件。

先决条件

Python包(所有平台):

pip install pwntools ropper ROPgadget

Linux(apt):

apt install gdb binutils strace ltrace qemu-system-x86

macOS(Homebrew):

brew install gdb binutils qemu

Ruby gems(所有平台):

gem install one_gadget seccomp-tools

手动安装:

  • pwndbg — Linux:GitHub,macOS:brew install pwndbg/tap/pwndbg-gdb
  • checksec — 包含在pwntools中

附加资源

  • overflow-basics.md - 栈/全局缓冲区溢出、ret2win、canary绕过、针对fork服务器的canary逐字节暴力破解、结构体指针覆盖、有符号整数绕过、隐藏gadget、基于步长的越界读取泄露、通过未检查memcpy长度及被调用者保存寄存器恢复导致的解析器栈溢出
  • rop-and-shellcode.md - 核心ROP链(ret2libc、系统调用ROP、rdx控制、shell交互)、ret2csu、坏字符XOR绕过、异类x86 gadget(BEXTR/XLAT/STOSB/PEXT)、通过xchg rax,esp进行栈迁移、sprintf() gadget链用于坏字符绕过、canary XOR结尾作为RDX清零gadget、stub_execveat系统调用作为通过read()返回值的execve替代
  • rop-advanced.md - 高级ROP技术:通过leave;ret进行双重栈迁移到BSS、带UTF-8约束的SROP(信号返回导向编程)、seccomp绕过、用于seccomp绕过的RETF架构切换(x64→x32)、带输入反转的shellcode、.fini_array劫持、ret2vdso、pwntools模板、用于seccomp绕过的x32 ABI系统调用别名、基于时间的盲shellcode泄露
  • format-string.md - 格式化字符串利用(泄露、GOT覆盖、盲pwn、过滤器绕过、canary泄露、__free_hook、.rela.plt修补、保存的EBP覆盖用于.bss迁移、argv[0]覆盖用于栈崩溃信息泄露、.fini_array循环用于多阶段利用、通过顺序%p绕过__printf_chk、单次调用泄露+GOT覆盖、通过输入变换的ROT13编码格式化字符串利用)
  • advanced.md - Seccomp高级技术、UAF、JIT、深奥的GOT、通过进制转换的堆重叠、树数据结构栈分配不足、ret2dlresolve、内核利用(基础)
  • heap-techniques.md - House of Apple 2(+ setcontext SUID变体)、House of Einherjar、House of Orange/Spirit/Lore/Force、堆整理、自定义分配器(nginx、talloc)、经典unlink、musl libc堆(元指针+atexit劫持)、tcache stashing unlink攻击、不安全unlink + top chunk合并
  • heap-techniques-2.md - CTF writeup堆变体:UAF虚表指针编码shell参数、未初始化chunk残留指针泄露、tcache strcpy空字节溢出+向后合并、相邻结构体函数指针溢出用于libc泄露+GOT覆盖、隐藏菜单tcache投毒、tcache双重释放+伪造_IO_FILE虚表stdout劫持、tcache到fastbin的跨bin提升攻击、6位索引越界+written_bytes累加器、IS_MMAPED位翻转用于calloc'd chunk的unsorted bin泄露、文件名正则约束的fastbin通过仅LSB的堆指针覆盖、自定义分配器不安全unlink到GOT
  • heap-fsop.md - FILE结构(_IO_FILE)利用:fastbin stdout虚表两阶段劫持用于PIE+Full RELRO、_IO_buf_base空字节stdin劫持、glibc 2.24+ _IO_FILE虚表验证绕过、针对stdin _IO_buf_end的unsorted-bin攻击、通过mp_结构的unsorted-bin破坏、realloc(ptr, 0)作为free() UAF、单字节引用计数器回绕UAF
  • advanced-exploits.md - 高级利用技术(第1部分):VM有符号比较、BF JIT shellcode、类型混淆、差一索引破坏、DNS溢出、ASAN影子内存、带编码约束的格式化字符串、自定义canary保护、有符号整数绕过、canary感知的部分溢出、CSV注入、MD5原像gadget、VM GC UAF slab重用、路径遍历清理器绕过、通过openat/mmap/write的FSOP+seccomp绕过
  • advanced-exploits-2.md - 高级利用技术(第2部分):通过自修改的字节码验证器绕过、带SQE注入的io_uring UAF、整数截断int32->int16、GC空引用级联破坏、通过多fgets stdout FILE覆盖的无泄露libc、有符号/无符号char下溢堆溢出、XOR密钥流暴力写入原语、tcache指针解密堆泄露、通过伪造chunk大小的unsorted bin提升、FSOP stdout TLS泄露、通过__call_tls_dtors的TLS析构函数劫持、自定义影子栈指针溢出绕过、有符号int溢出负值越界堆写入、XSS到二进制pwn桥接
  • advanced-exploits-4.md - 高级利用技术(第4部分):Windows SEH覆盖+pushad VirtualAlloc ROP、IAT相对解析、分离进程shell稳定性、SeDebugPrivilege SYSTEM提权、ARM缓冲区溢出带Thumb shellcode、Forth解释器system词利用、GF(2)高斯消元用于多阶段tcache投毒、单比特翻转利用原语(mprotect+迭代代码修补)、Game of Life shellcode通过静止图案演化、通过菜单驱动strdup/free顺序的UAF、Windows CFG绕过通过system()作为有效调用目标、神经网络输出作为函数指针索引越界、通过计数器溢出的shellcode唯一字节限制绕过
  • advanced-exploits-3.md - 高级利用技术(第3部分):栈变量重叠/进位破坏越界、通过8位循环计数器的1字节溢出、游戏AI算术均值越界读取、任意读/写GOT覆盖到shell、通过__environ+memcpy溢出的栈泄露、通过uint16跳转截断的JIT沙箱逃逸、带多问题ROP的DNS压缩指针栈溢出、通过程序头操作的ELF代码签名绕过、游戏关卡格式有符号/无符号坐标不匹配、通过缺少O_CLOEXEC的文件描述符继承、元数据解析中的符号扩展整数下溢、带只读原语的ROP链构建、通过持久寄存器的4字节shellcode带定时侧信道、CRC预言机作为任意读取、UTF-8大小写转换缓冲区溢出
  • advanced-exploits-5.md - 高级利用技术(第5部分):数据解释利用——Chip-8模拟器越界内存用于ret2libc、双精度浮点快速排序canary重定位、布隆过滤器abs(INT_MIN)负索引越界写入
  • sandbox-escape.md - 自定义VM利用、FUSE/CUSE设备、busybox/受限shell、shell技巧、process_vm_readv沙箱绕过、命名管道文件大小绕过、CPU模拟器打印操作码Python eval注入(交叉引用ctf-misc/pyjails.md了解Python沙箱技术)
  • kernel.md - Linux内核利用基础:环境搭建、QEMU调试、堆喷结构(tty_struct、poll_list、user_key_payload、seq_operations)、内核栈溢出、canary泄露、权限提升(ret2usr、内核ROP)、modprobe_path覆盖、core_pattern覆盖、kmalloc大小不匹配堆溢出+struct file f_op破坏
  • kernel-techniques.md - 内核利用技术:tty_struct kROP(伪造虚表+栈迁移)、通过ioctl寄存器控制的AAW、userfaultfd竞争稳定化、SLUB分配器内部(freelist加固/混淆)、通过内核恐慌泄露、MADV_DONTNEED竞争窗口扩展(DiceCTF 2026)、跨缓存CPU分裂攻击(DiceCTF 2026)、PTE重叠文件写入(DiceCTF 2026)、通过失败文件打开的addr_limit绕过用于内核内存读/写
  • kernel-bypass.md - 内核保护绕过:KASLR/FGKASLR绕过(__ksymtab)、KPTI绕过(swapgs trampoline、信号处理程序、通过ROP的modprobe_path/core_pattern)、SMEP/SMAP绕过、GDB内核模块调试、initramfs/virtio-9p工作流、利用模板、利用投递
  • field-notes.md - 详细pwn笔记:堆利用快速参考、额外利用笔记、有用命令

何时切换

  • 如果你还不了解二进制文件的功能,先切换到/ctf-reverse再尝试利用。
  • 如果服务实际上是受限shell、编码谜题或沙箱语言挑战,切换到/ctf-misc
  • 如果利用路径依赖于Web端点、会话漏洞或上传原语而非内存损坏,切换到/ctf-web
  • 如果漏洞需要在利用前破解密码学原语,切换到/ctf-crypto

快速启动命令

# 二进制分析
checksec --file=binary
file binary
readelf -h binary

# 查找gadget
ROPgadget --binary binary | grep "pop rdi"
ropper -f binary --search "pop rdi"
one_gadget /lib/x86_64-linux-gnu/libc.so.6

# 调试
gdb -q binary -ex 'start' -ex 'checksec'

# 偏移查找模式
python3 -c "from pwn import *; print(cyclic(200))"
python3 -c "from pwn import *; print(cyclic_find(0x61616168))"

# libc识别
./libc-database/find puts <leaked_addr_last_3_nibbles>

源代码危险信号

  • 线程/pthread -> 竞争条件
  • usleep()/sleep() -> 时间窗口
  • 多线程中的全局变量 -> TOCTOU

竞争条件利用

bash -c '{ echo "cmd1"; echo "cmd2"; sleep 1; } | nc host port'

常见漏洞

  • 缓冲区溢出:gets()scanf("%s")strcpy()
  • 格式化字符串:printf(user_input)
  • 整数溢出、UAF、竞争条件

保护对利用策略的影响

保护 状态 影响
PIE 禁用 所有地址(GOT、PLT、函数)固定——直接覆盖有效
RELRO 部分 GOT可写——GOT覆盖攻击可能
RELRO 完整 GOT只读——需要替代目标(hooks、虚表、返回地址)
NX 启用 无法在栈/堆上执行shellcode——使用ROP或ret2win
Canary 存在 检测到栈溢出——需要泄露或避免栈溢出(使用堆)

快速决策树:

  • 部分RELRO + 无PIE -> GOT覆盖(最简单,使用固定地址)
  • 完整RELRO -> 目标__free_hook__malloc_hook(glibc < 2.34)或返回地址
  • 栈canary存在 -> 优先使用基于堆的攻击或先泄露canary

栈缓冲区溢出

  1. 查找偏移:cyclic 200 然后 cyclic -l <value>
  2. 检查保护:checksec --file=binary
  3. 无PIE + 无canary = 直接ROP
  4. 通过格式化字符串或部分覆盖泄露canary
  5. 针对fork服务器逐字节暴力破解canary(最多7*256次尝试)

带魔法值的ret2win: 溢出 -> ret(对齐)-> pop rdi; ret -> 魔法值 -> win()。栈对齐: movaps中的SIGSEGV = 添加额外ret gadget。偏移: 缓冲区在rbp - N,返回地址在rbp + 8,总计 = N + 8。输入过滤: 确保payload避免memmem()禁止的字符串。Gadget: ROPgadget --binary binary | grep "pop rdi",或pwntools ROP()用于CMP立即数中的隐藏gadget。完整利用代码见overflow-basics.md

解析器栈溢出(未检查的memcpy)

模式: 自定义文件解析器(PCAP、图像、存档)分配固定栈缓冲区,但输入记录可能超过它。memcpy在长度验证前复制,溢出保存的寄存器和返回地址。必须恢复被调用者保存的寄存器:rbx到可读内存(BSS)、循环计数器到退出值,然后ret gadget + win函数。见overflow-basics.md

结构体指针覆盖(堆菜单挑战)

模式: 菜单创建/修改/删除带有数据缓冲区和指针的结构体。用GOT地址溢出名称到指针字段,然后通过修改写入win地址。完整利用和GOT目标选择表见overflow-basics.md

有符号整数绕过

模式: scanf("%d")无符号检查;负数数量*价格=负总数,绕过余额检查。见overflow-basics.md

Canary感知的部分溢出

模式: 溢出缓冲区与canary之间的valid标志。使用./作为无操作路径填充以达到精确长度。完整利用链见overflow-basics.mdadvanced.md

全局缓冲区溢出(CSV注入)

模式: 相邻的全局变量;通过额外CSV分隔符溢出改变文件名指针。完整利用见overflow-basics.mdadvanced.md

ROP链构建

通过puts@PLT(puts@GOT)泄露libc,返回到漏洞函数,第二阶段使用system("/bin/sh")。完整的二阶段ret2libc模式、泄露解析和返回目标选择见rop-and-shellcode.md

DynELF libc发现: pwntools.DynELF(leak_func, pointer_in_libc)远程解析libc符号,无需知道libc版本。见rop-and-shellcode.md

小缓冲区中的受限shellcode: 当缓冲区太小时,使用read() shellcode存根(<20字节)拉取完整的第二阶段shellcode。见rop-and-shellcode.md

原始系统调用ROP:system()/execve()崩溃(CET/IBT)时,使用来自libc的pop rax; ret + syscall; ret。见rop-and-shellcode.md

ret2csu: __libc_csu_init gadget控制rdxrsiedi并调用任何GOT函数——无需libc gadget的通用三参数调用。见rop-and-shellcode.md

坏字符XOR绕过: 在写入.data之前用密钥XOR payload数据,然后使用ROP gadget原地XOR回来。避免空字节、换行符和其他过滤字符。见rop-and-shellcode.md

异类gadget(BEXTR/XLAT/STOSB/PEXT): 当标准mov写入gadget不可用时,链接晦涩的x86指令进行逐字节内存写入。见rop-and-shellcode.md

栈迁移(xchg rax,esp): 当溢出太小无法容纳完整ROP链时,将栈指针交换到攻击者控制的堆/缓冲区。需要先加载pop rax; ret来加载迁移地址。见rop-and-shellcode.md

rdx控制:puts()之后,rdx被破坏为1。使用来自libc的pop rdx; pop rbx; ret,或重新进入二进制文件的读取设置+栈迁移。见rop-and-shellcode.md

Canary XOR结尾作为rdx清零gadget: 当没有pop rdx; ret时,跳转到canary检查结尾xor rdx, fs:28h——当canary完整时,它将RDX清零。见rop-and-shellcode.md

stub_execveat作为execve替代: 当没有pop rax; ret时,使用stub_execveat(系统调用322/0x142)代替execve——发送恰好0x142字节,使read()返回值设置rax。见rop-and-shellcode.md

Shell交互:execve之后,sleep(1)然后sendline(b'cat /flag*')。见rop-and-shellcode.md

通过输入变换的格式化字符串

ROT13编码的格式化字符串: 当输入在到达printf之前经过ROT13/Caesar变换时,用逆变换预编码格式化字符串payload,使其完整到达。见format-string.md

内核利用

通过失败文件打开的addr_limit绕过: 当内核模块设置addr_limit = KERNEL_DS但未在错误路径上恢复时,强制错误(例如,使目标文件成为目录)以保留从用户空间read()/write()的内核内存访问。见kernel-techniques.md

沙箱和模拟器逃逸

CPU模拟器eval注入: 当模拟器的打印操作码使用eval('"' + buf + '"')进行转义序列时,通过ADD操作码在模拟器内存中构建"+__import__("os").system("cmd")#以逃出字符串并执行Python。见sandbox-escape.md

高级利用原语

神经网络函数指针越界: 当二进制文件使用NN输出作为函数指针数组的索引而无边界检查时,重新训练权重/偏置以产生越界索引,从偏置数组中读取目标地址。见advanced-exploits-4.md

通过计数器溢出的shellcode唯一字节限制绕过: 当shellcode限制为N个唯一字节时,喷射栈以破坏seen[256]计数器,然后重新执行main(跳过memset),使溢出的计数器允许第二次运行时使用任意字节。见advanced-exploits-4.md

深入笔记

一旦确认挑战确实是利用密集型,使用field-notes.md

  • 堆和分配器笔记:House of Apple、tcache、不安全unlink、talloc、UAF、FSOP
  • 高级利用笔记:seccomp绕过、ret2vdso、io_uring、整数截断、ASAN、定时预言机
  • 沙箱和混合笔记:pyjail交叉、busybox逃逸、自定义VM、shell技巧、路径清理器
  • 内核和Windows笔记:内核手册、SEH、CFG绕过、权限提升
  • 历史案例笔记:较旧但仍可重用的CTF利用模式