Lukas' Notes

security memory

Definition

Control-Flow Hijacking

Control-flow hijacking is the goal class of binary-exploitation attacks: make the target program execute attacker-controlled code by exploiting a buffer overflow. The high-level programming model assumes execution flows along the paths the source code describes; the attacker’s job is to break that assumption by corrupting the data the CPU uses to direct execution, so that a ret, a call, or an indirect jump goes somewhere the program never intended.

Assumptions vs Reality

The execution-model assumptions exploitation breaks

High-level languages — including C — sit on an execution model with built-in assumptions:

  • basic statements are atomic (a single assignment does one thing);
  • functions start at the beginning and run until the end;
  • when a function ends, execution returns to its call site;
  • only one branch of an if is taken at a time;
  • only program code can be executed;
  • the set of executable instructions is limited to those emitted during compilation.

At the level of machine code none of these hold:

  • a single statement compiles to several instructions, so execution can be interrupted mid-statement;
  • execution can start in the middle of a function;
  • ret can jump to any program location — the saved return address is just data on the stack;
  • there are no restrictions on branch targets;
  • dead code (unused library functions, unreachable win routines) can be executed;
  • on x86-64 execution can even start in the middle of an instruction, because instruction boundaries are decoded, not declared.

The Exploit Pattern

The four stages of a control-flow hijack

Every attack in this lecture cluster follows the same shape:

  1. Recon — find a bug in the target program (a missing bounds check, an unsafe call);
  2. Development — write code that exploits the bug (an overflow length, a saved-address overwrite, a payload);
  3. Feed — deliver the exploit to the vulnerable program (an argument, a network packet, a crafted input);
  4. Hijack — the program executes under attacker control.

The recon and development stages are where static and dynamic analysis pay off; the feed and hijack stages are where the technique notes — instruction pointer hijacking, ROP, ret2libc, ret2plt — operate.