Chapter 37 Exercises: Return-Oriented Programming and Modern Exploitation
🔐 Security Note: All exercises are for defensive education. Understanding ROP is essential for security defenders, compiler engineers building CFI systems, and systems programmers who need to understand why modern mitigations are designed as they are. Exercises involving ROP chain analysis are performed in controlled lab environments on machines you own.
Conceptual Exercises
Exercise 37.1 — Why ROP exists Answer these questions about the motivation for ROP:
a) NX/DEP was deployed in the early 2000s. What specific attack did it prevent?
b) What property of ret does ROP exploit?
c) Why does every large binary contain thousands of potential gadgets?
d) Why is RISC architecture (like ARM64 with 4-byte aligned instructions) more resistant to "unintended gadgets" than x86-64?
Exercise 37.2 — Gadget identification For each instruction sequence, determine whether it is a useful ROP gadget and describe what it does:
; Sequence A:
pop rax
ret
; Sequence B:
push rdi
push rsi
ret
; Sequence C:
nop
nop
nop
ret
; Sequence D:
pop rcx
pop rdx
pop rbx
ret
; Sequence E:
xor rax, rax
ret
; Sequence F:
mov [rdi], rax
add rsp, 8
ret
Exercise 37.3 — Unintended gadgets Given these bytes at address 0x401234:
48 89 c7 → mov rdi, rax (3 bytes)
c3 → ret (1 byte)
a) What is the intended gadget at 0x401234?
b) What gadget exists at 0x401237 (the c3 byte alone)?
c) Why does x86-64's variable-length encoding enable these "unintended" gadgets?
d) Why would ARM64 (4-byte fixed-width instructions, 4-byte aligned) not have an equivalent "unintended gadget" at 0x401237?
Chain Construction Exercises (Conceptual)
Exercise 37.4 ⭐ — Chain tracing Trace through this ROP chain execution, filling in the register values after each gadget:
Gadgets available:
- pop rdi; ret at 0x401200
- pop rax; ret at 0x401210
- xor rsi, rsi; ret at 0x401220
Forged stack:
RSP+0: 0x401200 (gadget 1)
RSP+8: 0xdeadbeef (value)
RSP+16: 0x401210 (gadget 2)
RSP+24: 0x00000042 (value)
RSP+32: 0x401220 (gadget 3)
RSP+40: (next item after chain)
Fill in this table:
| After gadget | RDI | RAX | RSI | RSP (relative) |
|---|---|---|---|---|
| Initial | ? | ? | ? | RSP+0 |
| After gadget 1 | ? | ? | ? | ? |
| After gadget 2 | ? | ? | ? | ? |
| After gadget 3 | ? | ? | ? | ? |
Exercise 37.5 — Required gadgets For each goal, list the gadgets you would need and the order they would appear in the chain:
a) Call puts(string_ptr) where string_ptr is a known address
b) Set RAX = 60, RDI = 0, then execute a syscall (this is exit(0))
c) Set all of RAX, RDI, RSI, RDX to specific values, then execute syscall
Exercise 37.6 ⭐ — ret2libc without ASLR
A binary without ASLR or PIE has a stack overflow. libc is loaded at 0x7ffff7a00000. In libc:
- system is at offset 0x55410
- /bin/sh string is at offset 0x1b75aa
- pop rdi; ret gadget is at 0x23a5f from the binary base 0x400000
a) What is the runtime address of system?
b) What is the runtime address of the /bin/sh string?
c) What is the runtime address of the pop rdi; ret gadget?
d) Write out the forged stack contents (addresses in hex) to call system("/bin/sh")
Tool Usage Exercises
Exercise 37.7 — ROPgadget usage Write the ROPgadget commands for:
a) Find all gadgets in a binary called ./target
b) Find all gadgets containing pop rdi
c) Find all gadgets ending in syscall (not just ret)
d) Search libc for gadgets: ROPgadget --binary /lib/x86_64-linux-gnu/libc.so.6 --rop | grep "pop rdi"
Exercise 37.8 — Gadget analysis from ROPgadget output Given this ROPgadget output for a small binary:
0x0000000000401200 : pop rdi ; ret
0x0000000000401208 : pop rsi ; pop r15 ; ret
0x0000000000401218 : pop rbp ; ret
0x000000000040121a : ret
0x0000000000401234 : nop ; ret
0x0000000000401240 : xor eax, eax ; ret
0x0000000000401250 : mov edi, eax ; ret
0x0000000000401258 : add rsp, 0x8 ; ret
a) Which gadget would you use to set RDI to a specific value?
b) Which gadget would you use to set RAX to 0?
c) Why might pop rsi ; pop r15 ; ret be less preferable than a pure pop rsi ; ret?
d) What does add rsp, 0x8 ; ret do to the chain execution? When might this be useful?
Exercise 37.9 ⭐ — Gadget quality evaluation For each pair of gadgets that accomplish the same goal, choose the better one and explain why:
a) Setting RDI:
- push rax; pop rdi; ret (from unintended bytes at 0x401156)
- pop rdi; ret (from function prologue at 0x401200)
b) Setting RAX to 0:
- xor eax, eax; ret (3+1 bytes)
- mov rax, 0; ret (7+1 bytes)
c) Calling a function:
- call system; ret (direct call, 5+1 bytes)
- push <system_addr>; ret (push the address, then the "ret" calls it) — is this valid?
SROP and Advanced Technique Exercises
Exercise 37.10 — SROP conceptual Answer these questions about Sigreturn-Oriented Programming:
a) What is the sigreturn syscall number on Linux x86-64?
b) What structure does sigreturn pop from the stack?
c) How many gadgets does a basic SROP chain require? What is the gadget?
d) What values in the sigcontext structure would you set to call execve("/bin/sh", NULL, NULL)?
e) How does CET's SHSTK interact with SROP?
Exercise 37.11 ⭐ — JOP vs ROP Compare JOP (Jump-Oriented Programming) and ROP:
a) In ROP, what instruction chains gadgets? In JOP? b) Why did JOP become relevant after SHSTK deployment? c) What CET component specifically addresses JOP gadgets? d) Is JOP easier or harder to chain than ROP? Explain.
Exercise 37.12 — Blind ROP concepts Describe the Blind ROP technique step by step, for the purpose of understanding why server security matters:
a) Why can BROP work when ASLR is enabled? b) What property of fork()-based servers enables BROP? c) How does "re-exec on fork" defeat BROP? d) What mitigation directly addresses the information leakage that BROP exploits?
Mitigation Analysis Exercises
Exercise 37.13 ⭐ — Mitigation effectiveness against ROP Rate each mitigation's effectiveness against a ROP chain (Strong / Moderate / Weak / None) and explain:
| Mitigation | Effectiveness vs. ROP | Reason |
|---|---|---|
| Stack canary | ? | ? |
| NX/DEP | ? | ? |
| ASLR (no PIE) | ? | ? |
| ASLR + PIE | ? | ? |
| Full RELRO | ? | ? |
| CET SHSTK | ? | ? |
| CET IBT | ? | ? |
| Clang CFI-icall | ? | ? |
Exercise 37.14 — Information leak analysis A server has NX + Canary + ASLR + PIE + Full RELRO. An attacker finds an out-of-bounds read vulnerability that can leak one 8-byte value at a specified stack offset.
a) What value at the stack offset would be most useful to leak? Why? b) How does knowing one libc address break ASLR for the entire libc? c) Even with all addresses known, what additional mitigation still prevents a ROP chain? d) If CET SHSTK is also enabled, what would an attacker need beyond address knowledge?
Exercise 37.15 ⭐ — Chain structure analysis This forged stack is part of a ret2plt information leak chain (all addresses are illustrative):
RSP+0: 0x401200 (pop rdi; ret gadget in executable)
RSP+8: 0x404018 (address of puts@GOT)
RSP+16: 0x401040 (puts@PLT)
RSP+24: 0x401360 (main function, to restart program)
a) What does gadget 1 do?
b) What does step 2 (puts@PLT call) accomplish?
c) What does redirecting to main accomplish?
d) How does the attacker use the output of puts to calculate the libc base?
Deep-Dive Exercises
Exercise 37.16 — Turing completeness of ROP Shacham (2007) proved ROP is Turing complete. For each primitive needed for Turing completeness, identify an x86-64 gadget sequence that implements it:
a) Load a constant into a register b) Load from memory c) Store to memory d) Add two registers e) Conditional behavior (hint: this requires a non-obvious gadget strategy)
Exercise 37.17 ⭐ — Complete defensive chain analysis You are a security engineer reviewing a server binary. Describe your complete analysis process:
- Run
checksec— what do you look for? - Run
ROPgadget— what makes you concerned? - What source code patterns increase the gadget surface?
- What build flags reduce the effective gadget surface?
- What hardware feature provides the strongest guarantee against ROP chains?
Exercise 37.18 — ret2plt deep understanding In a ret2plt chain, why is it important to call a function through the PLT rather than directly:
a) What address does puts@PLT contain? What address does puts@GOT contain?
b) Why does calling puts@PLT cause puts to actually execute?
c) After calling puts(puts@GOT), what is the output, and how is it interpreted?
d) What calculation converts a leaked puts address to a libc base address?
Exercise 37.19 — SafeStack vs SHSTK Compare SafeStack (Clang software) and CET SHSTK (Intel hardware):
a) What does SafeStack separate and how? b) Why is SHSTK more secure than SafeStack? c) When would you prefer SafeStack over SHSTK? d) Can a heap overflow bypass SafeStack? Can it bypass SHSTK?
Exercise 37.20 ⭐ — Full exploitation chain design (conceptual) A server has NX + Canary + ASLR + PIE + Partial RELRO. It has TWO vulnerabilities: 1. A format string bug in the error handler that reads stack values 2. A buffer overflow that overwrites the return address
Design the CONCEPTUAL stages of an exploitation chain: - Stage 1 uses vulnerability 1 for what purpose? - Stage 2 uses vulnerability 2 to do what? - What information gathered in Stage 1 is needed in Stage 2? - Why does the Partial RELRO (not Full) matter for Stage 2?