Spirine
Spirine

Reputation: 1877

How to exploit a buffer overflow to execute instructions on the stack

I'm starting to tinker with buffer overflows, and wrote the following program:

#include <unistd.h>

void g() {
  execve("/bin/sh", NULL, NULL);
}

void f() {
  long *return_address;
  char instructions[] = "\xb8\x01\x00\x00\x00\xcd\x80"; // exit(1)

  return_address = (long*) (&return_address + 2);
  *return_address = (long)&g; // or (long)instructions
}

int main() {
  f();
}

It does what I expect it to do : return_address overwrite the return address of f with the address of g, which opens a shell. However, if I set the return address to instructions, I got a segmentation fault, and none of the instructions in instructions is executed.

I compile with GCC, using -fno-stack-protector.

How could I prevent this segmentation fault occurring ?

Upvotes: 4

Views: 443

Answers (1)

Ray
Ray

Reputation: 1993

At least one problem isn't related to the buffer overflow.

execve("/bin/sh", NULL, NULL);

That first NULL becomes the argv of the process you're starting. argv must be an array of strings that is terminated with a NULL. So a segfault may happen when /bin/sh starts up, tries to read argv[0], and dereferences NULL.

void g(void) {
    char *argv[] = { "/bin/sh", NULL };
    execve(argv[0], argv, NULL);
}

You might also add -z execstack to the gcc command line, which will tell the linker to permit an executable stack. You should also verify that the instructions you have there are what exit(1) compiles to on your system if you got them from a tutorial somewhere.

Upvotes: 2

Related Questions