Reputation: 1877
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
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