# CSC 472 • Week 10 • October 27 & 29, 2026 # Class 15: Multi-Stage Exploits • Class 16: StackGuard & Format String Dr. Si Chen • West Chester University These classroom demonstrations adapt the instructor's course archive, Chapters 16-17 (the capstone of the code-reuse unit, continuing Chapters 13-15: ret2libc, ret2plt, GOT overwrite). Run them in your WolfCTF lab terminal at https://portal.wolfctf.com/labs/lab1 (GDB + GEF included). All commands run inside the Linux terminal, not macOS/Windows. They create a separate ~/csc472-week10 directory and do not touch your Lab files. COURSE USE ONLY. Build and run only the included binaries in your own lab terminal, never against systems you do not own. ## Get the files cd ~ curl -fLO https://wcu.ninja/files/CSC472_Week10_code.tar.gz tar -xzf CSC472_Week10_code.tar.gz cd ~/csc472-week10 Prereqs (already in the lab image): pip install pwntools ROPgadget ## Class 15: Multi-Stage Exploits (Tuesday, October 27) cd ~/csc472-week10/class15 make # gcc -m32 -fno-stack-protector -z noexecstack -no-pie make checknx # GNU_STACK = RW -> NX is ON make info # write@plt/read@plt, write@GOT, &scratch, the gadget The idea: by now NX (no injected code) and ASLR (libc moved) are both ON. The binary is -no-pie, so its PLT/GOT/.bss are FIXED. It imports only read and write. We chain them -- in ONE process, because every stage returns into main() so the randomized libc base stays alive between stages. echo 2 | sudo tee /proc/sys/kernel/randomize_va_space # ASLR ON (the point) python3 multi_stage.py # -> shell; try `id`, then `exit` Four stages, whole ROP chain fits in read(0, buf, 100)'s 100 bytes: stage 1 write(1, write@GOT, 4) leak write()'s real libc address libc_base = leaked - libc.sym.write stage 2 read(0, &scratch, 8) drop "/bin/sh\0" into fixed .bss read(0, write@GOT, 4) overwrite write@GOT with &system stage 3 write@plt(&scratch) PLT stub now jumps to system -> shell cdecl puts args on the stack, so a `pop; pop; pop; ret` gadget cleans each call's 3 arguments between links. Find the 28-byte overflow offset the Lab 1 way: De Bruijn pattern -> read EIP in gdb -> cyclic_find(). ## Class 16: StackGuard & Format String Bug (Thursday, October 29) cd ~/csc472-week10/class16 make # easy_canary (canary ON) + fmt_wrong + fmt_write (OFF) make checkcanary # proves which binaries carry __stack_chk_fail Part 1 -- brute-force a stack canary. A canary is a random word between the locals and the saved return address, checked on return, so an overflow is caught before EIP is used. easy_canary is a FORKING server: fork() copies the parent's canary, so every child shares one value. Recover it byte by byte -- `ALIVE` means the guessed byte was right, a silent death means wrong: ./easy_canary # terminal 1 -- leave running (127.0.0.1:4444) python3 easy_canary.py # terminal 2 -- recovers canary, hits win() win() prints "[win] canary bypassed ..." on the SERVER console -- it is the hijacked return, not a reply to the client. Part 2 -- format string bugs. printf(user_input) lets us name arguments that were never passed, so printf walks the stack. python3 fmt_wrong.py # leak: AAAA.%N$p until 41414141 -> our arg #4 make token # &token for the write python3 fmt_write.py # %n write: flips token 0xdeadbeef -> 0xcafebabe %n stores the characters-printed count into a pointer argument -> arbitrary write with no overflow. %n=DWORD, %hn=WORD, %hhn=BYTE. The same bug can leak the stack canary (defeating Part 1 without brute force) and leak a libc address under ASLR (the exact information leak Class 15 relied on). ## Why this is the defensive payoff of the whole unit No single mitigation ends exploitation; the layers together raise the cost: NX/DEP stops injected shellcode -> forces code reuse (ROP) ASLR hides the libc base -> forces an info leak Stack canary catches the overflow pre-ret -> forces a leak or brute Full RELRO GOT read-only -> kills GOT overwrite (stage 2) Don't write it printf("%s", buf), bounded reads, memory-safe languages This week closes the memory-corruption arc: Week 11 moves to the heap. ## This week Quiz 4 in class. Lab 3 (Multi-Stage Exploits) is assigned this week; the D2L announcement is authoritative for the due date.