Stack Pivoting

Pivoting for more space, or freedom of payload

TLDR

Requirements

  1. Somewhere to pivot to obviously (.bss, buffer on the stack)

  2. Stack Pivoting Gadget - something that controls RSP

    1. leave ret

    2. pop rsp

What can you do with this?

  • Gain more space for your ROP chain/Shellcode ๐Ÿ˜„

// gcc source.c -o vuln -no-pie
#include <stdio.h>

void winner(int a, int b) {
    if(a == 0xdeadbeef && b == 0xdeadc0de) {
        puts("Great job!");
        return;
    }
    puts("Whelp, almost...?");
}

void vuln() {
    char buffer[0x60];
    printf("Try pivoting to: %p\n", buffer);
    fgets(buffer, 0x80, stdin);
}

int main() {
    vuln();
    return 0;
}
  • fgets call means that there is a limited number of bytes we can overflow -> not enough for a rop chain

    • we also have a leak to start of buffer, but not enough to craft a full ROP chain

    • to pass in the right values to the win function, we need to pass the values into rdi and rsi

  • Using stack pivot, we format our payload with a pop rsp..;ret gadget which will change the rip to the location we control (our buffer in this case), executing the rop chain stored in the buffer.

Example 2

  1. The binary reads in 4096 bytes into .bss at 0x4040e0, with the first 24 bytes (0x18) copied onto the stack via memcpy

    1. This gives us 3 gadgets worth of space to pivot to the address 0x4040e0

    2. We can use a leave ret gadget to pivot to this address

  2. leave ret gadget is essentially just this

  1. If we have a pop rbp gadget, we can essentially control where the binary returns to (address of .bss)

  2. This gives us ample space for our libc leak via puts as well as our ret2libc payload

Last updated