Lukas' Notes

security memory

Definition

Stack Pivot

A stack pivot is the technique of moving the stack pointer to a location the attacker controls, usually by overwriting the saved base pointer during the stack corruption subclass called frame pointer hijacking. The pivot relocations of rsp away from the genuine call stack to a .bss buffer, a heap chunk, or a larger buffer the attacker also wrote — anywhere the full ROP chain cannot fit in the original overflowed buffer.

Mechanics

Why an overwritten rbp moves rsp

The standard function epilogue is leave; ret, which expands to:

leave   ≡   mov rsp, rbp ; pop rbp
ret     ≡   mov rip, [rsp] ; add rsp, 8

If the saved rbp was overwritten by the overflow to point at attacker-controlled memory, then on the next leave:

  • mov rsp, rbp sets rsp to the attacker’s chosen location;
  • pop rbp reads one qword from there into rbp (the attacker can put a useful pointer for a subsequent pivot here);
  • the following ret pops the next qword off that controlled memory into rip.

From that point the controlled memory acts as the stack, and a ROP chain laid out there runs as if it were the return sequence.

Constrained Buffer Motivation

When the original buffer cannot hold a full chain

A real-world vulnerable buffer is often small — a few dozen bytes, far less than the several gadgets plus arguments a useful chain needs. The pivot is the answer: write only enough into the small buffer to overwrite the saved rbp with the address of a larger controlled region (any .bss static buffer the program keeps around, any heap chunk the allocator returns to the attacker, any field the attacker has been able to prime). Then move the frame pointer to that region, and the full chain lives there. The pivot is the ROP-equivalent of redirecting the channel rather than widening it.

Pivot Gadgets

The instruction snippets that perform a pivot

Standard pivot gadgets in a binary’s code include:

  • add rsp, <imm> ; ret — skip past the constrained buffer to controlled memory further down;
  • sub rsp, <imm> ; ret — symmetric, for the other direction;
  • ret <imm> — near-return that also pops <imm> extra bytes, equivalent to a tunable rsp adjustment;
  • leave ; ret — the canonical gadget for an overwritten rbp;
  • xchg <reg>, rsp ; ret — swap a controlled register (the attacker has set it via earlier gadgets) into rsp directly.

A ret <imm> “ret sled” can be chained to absorb uncertainty about exactly where the controlled memory starts — the ROP equivalent of a NOP sled.