Pular para o conteúdo principal

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.

  1. Alocamos memória em outro lugar (heap, .data, etc.). Precisamos obter o endereço de uma região de memória controlável.
  2. Encadeamos os gadgets na nova stack ([Gadget 1] → [Gadget 2] → [Gadget 3] → ...)
  3. Usamos um gadget que muda o registrador RSP para nossa nova stack (mov rsp, rax + ret) (stack pivoting!)
  4. 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

  1. Heap (via malloc/free)
  2. Seção .data ou .bss
  3. Stack secundária (usando vazamento de endereço)
  4. 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