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, acall, 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
ifis 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;
retcan 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
winroutines) 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:
- Recon — find a bug in the target program (a missing bounds check, an unsafe call);
- Development — write code that exploits the bug (an overflow length, a saved-address overwrite, a payload);
- Feed — deliver the exploit to the vulnerable program (an argument, a network packet, a crafted input);
- 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.