Skip to content

Latest commit

 

History

History
32 lines (21 loc) · 2.39 KB

File metadata and controls

32 lines (21 loc) · 2.39 KB

C++ & Language Concepts

  • Arrays are just memory. A char buffer[64] is 64 contiguous bytes on the stack. There's nothing stopping code from writing past the end — the language trusts the programmer.
  • Not all input functions are equal. We learned the difference between gets(), fgets(), scanf(), and cin, and why some are unsafe by design. gets() was removed from the C standard entirely.
  • Pointers and memory layout. Building the payload with memset and memcpy made pointer arithmetic concrete — we were placing exact bytes at exact positions.
  • Binary file I/O. Writing the raw payload to payload.bin with ofstream in binary mode.
  • Little-endian byte ordering. Understanding why a 4-byte address gets written into memory backwards.

Security Concepts

  • The call stack — how functions store their local variables, the saved frame pointer, and the return address, and how overwriting the return address hijacks control flow.
  • The exploit anatomy — padding → return-address overwrite → NOP sled → shellcode, and why each piece is needed.
  • JMP ESP technique — using an instruction already present in memory to reliably reach our code, instead of guessing a raw stack address.
  • NOP sleds — a reliability trick to avoid needing pixel-perfect jump accuracy.
  • Position-independent shellcode — how shellcode resolves Windows API functions (like WinExec) at runtime by walking the PEB.

Tools & Workflow

  • Immunity Debugger — attaching to a running process, reading CPU registers (ESP, EIP), inspecting the stack, and searching modules for useful instructions.
  • Finding offsets — the crash-and-measure workflow with a unique pattern to pinpoint exactly where EIP gets overwritten.

The Most Important Lesson: Defenses Exist for a Reason

The exploit only worked because we turned off the protections Windows normally provides — DEP, ASLR, and stack canaries. Doing that by hand, and then watching the exploit succeed, gave us a real understanding of why those mitigations exist and what attack each one is designed to stop.

Where We'd Go Next

  • Rewrite the vulnerable program safely and prove the overflow no longer triggers.
  • Study how attackers bypass modern mitigations (e.g., ROP chains to defeat DEP) — at a conceptual level.
  • Explore memory-safe languages (Rust) that prevent this class of bug at compile time.