2

I have made a little toy program, compiled with ALSR disabled, that I want to exploit using stack-based buffer overflow:

// gcc stackexec0x1.c -Wl,-z,execstack -no-pie -fno-stack-protector -o stackexec0x1

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define SBUFSZ 0x100
#define LBUFSZ 0x800

int main(int argc, char* argv[]) {
    char buf[SBUFSZ];
    printf("# ");
    fgets(buf, LBUFSZ, stdin); // exploit this!
    printf("%s", buf);
    return 0;
}

I can easily overwrite the return address, saved on the stack, with a custom one. However, between consecutive runs of the program, the rsp register (just before ret) differs:

0x7ffdc114dc88
0x7ffeb97d5668
0x7ffd48027798
0x7ffdbf2e9ea8
0x7ffe036a5d78
0x7fff40595998

Computing the differences between the aboversp register values, one can see they are big. It would not be feasible put a NOP-sledge that covers most of them on the stack?

How can I conveniently choose a return address into the NOP-sledge + payload on the stack, so that it's executed (with high probability), when the function returns?

checksec:

checksec stackexec0x1
[*] '/home/nlykkei/exploit-dev/stackexec0x1/stackexec0x1'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x400000)
    RWX:      Has RWX segments
Shuzheng
  • 1,097
  • 4
  • 22
  • 37

1 Answers1

2

The GCC -no-pie option partly disables ASLR: the binary will be loaded at fixed base address (i.e. 0x400000); however, other memory segments (e.g. stack) may still be loaded at random base addresses.

To completely disable ASLR, you need to disable it system-wide using:

echo 0 | sudo tee /proc/sys/kernel/randomize_va_space

Now, the stack will be loaded at a fixed base address. The addresses below are values of rsp just before ret in main (examined using r2 -d):

0x7fffffffdfb8
0x7fffffffdfb8
0x7fffffffdfb8
0x7fffffffdfb8
0x7fffffffdfb8
0x7fffffffdfb8

Given this, it should be easy to choose a target address into your NOP-sledge.