OSEE study materials
OSEE study resources

OSEE: Exploit Development (OSEE / EXP-401)

OSEE · Work through your exam, one topic at a time.

All guide sections

Exploit Development (OSEE / EXP-401)

Exploit Development is the heart of the OSEE exam. You are not asked to find the bug - triage and root-cause may already be done for you - you are asked to weaponize a memory-corruption flaw against a Windows target and make it work repeatedly. Grading rewards reliability and understanding of why the chain works, not a one-shot crash-to-shell.

What is assessed

  • End-to-end exploitation: from controlled crash, to EIP/instruction-pointer control, to payload execution.
  • 32-bit and 64-bit Windows userland classes: stack overflows, SEH overwrites, heap and pool corruption, C++ vtable/object-lifetime bugs, and the integer issues that feed them.
  • Mitigations as obstacles to route around: stack cookies (/GS), SafeSEH and SEHOP, DEP, ASLR, and what each one does to your primitive.
  • Custom shellcode work: encoders, bad-character elimination, position independence, and payloads you built rather than payloads you downloaded.

Rules that decide the outcome

  • Enumerate bad characters before designing anything. The set changes the encoder, the usable gadget addresses, and whether a pointer can be written at all.
  • Work in order: control the instruction pointer, defeat ASLR (info leak or a non-ASLR module), defeat DEP (ROP or pivot), then solve payload space and stability.
  • Prefer the smallest deterministic primitive. A partial overwrite or clean stack pivot beats a heap spray that lands two runs in three.
  • Heap behaviour is only predictable when you control allocation order and size class; know whether your allocation is landing in the LFH before you groom.
  • Keep chains self-contained and re-entrant - never assume a register you did not set.

Worked example

A 32-bit file parser copies an attacker length into a 1,000-byte stack buffer with /GS compiled out, and the SEH record is overwritten at offset 1,024. SafeSEH is enforced in the main image, so no gadget there may be used as a handler. Search loaded modules for one linked without /SAFESEH and take a POP/POP/RET from it. nSEH receives a short forward jump over the handler slot (choosing bytes that survive the copy), the handler slot receives the POP/POP/RET address, and the jump lands on a ROP chain that calls VirtualProtect on the buffer and jumps into it. Reasoning: DEP blocks a direct jump to shellcode, and SafeSEH rejects a main-image handler, so the bypass must come from a module outside the SafeSEH table.

Traps that cost marks

  • Hardcoding a module base captured in a debugger where ASLR was disabled.
  • Forgetting the nSEH jump and letting the handler fire into garbage.
  • Using an address containing a bad character that truncates the overwrite.
  • Declaring success after a single run instead of repeated runs against a fresh target process.
  • Grooming the heap without accounting for allocations the target makes before your input is parsed.