Stack Pivoting
Às vezes não temos espaço suficiente na stack para colocar os gadgets ROP (stack limitada), ou a stack original está protegida.
A solução para isso é o stack pivoting: Vamos criar uma nova stack para usarmos os gadgets. Ou seja, mudamos para um lugar maior e mais livre onde temos mais espaço para trabalhar.
- Alocamos memória em outro lugar (heap, .data, etc.). Precisamos
obter o endereço de uma região de memória controlável. - Encadeamos os gadgets na nova stack ([Gadget 1] → [Gadget 2] → [Gadget 3] → ...)
- Usamos um gadget que muda o registrador RSP para nossa nova stack (
mov rsp, rax+ret) (stack pivoting!) - A CPU agora usa nossa nova stack.
Lembre-se que o ret é uma instrução compacta que na verdade executa pop rip. E lembre-se que pop usa rsp como referência para fazer o "pop" um elemento da stack. Assim, o pop rip pega o endereço para o qual rsp aponta e coloca no rip. Portanto, basta fazer mov rsp, rax
O Stack Pivoting dá bypass em ASLR/NX.
Resumindo: Stack Pivoting = Redirecionar RSP/ESP para região controlada + ROP chain pré-montada.
Encontrando a nova stack
- Heap (via malloc/free)
- Seção .data ou .bss
- Stack secundária (usando vazamento de endereço)
- Memória mapeada (mmap)
Gadgets comuns para pivoting
# 1. Movimento direto
mov esp, eax ; ret # Copia EAX para ESP
xchg esp, eax ; ret # Troca ESP com EAX
# 2. Aritmético
add esp, 0x100 ; ret # Aumenta ESP
sub esp, 0x100 ; ret # Diminui ESP
# 3. Indireto
push rax ; pop rsp ; ret # Move RAX para RSP via push/pop
Para o stack pivoting com rax funcionar, precisamos de um gadget pop_rax para colocar o endereço desejado em rax.
[Buffer overflow...]
[pop_rax_gadget] ← RIP vai aqui primeiro (return address)
[&nova_stack] # Valor para RAX
[mov_rsp_rax_gadget] # Gadget que faz pivot