2

When performing a format string exploit, how do you inject an address that contains 0x00?

#include<stdio.h>

int main(int argc,char *argv[])
{
    char buf[80];
    snprintf(buf, 79, argv[1]);
    printf(buf);
}

How would you get a ret to libc if, say, the address of system is 00112233 (Little endian)

Where the address of system contained a null byte. To use the printf vulnerability, your input was first passed through snprintf, which stopped at the first occurance of a null byte.

robertkin
  • 277
  • 2
  • 6

1 Answers1

3

First you'll probably need to enable support for the %n character as it is disabled by default on some operating systems. The vulnerable program would have to have the following statement:

_set_printf_count_output(1);

Next, you will need to determine where the return address you wish to overwrite is stored on the stack. In this case, you could overwrite either the return address of printf or main. One of these locations you will need to overwrite with the value 00112233.

You must overwrite the return address one byte at a time by generating an input to printf to be the equivalent of

printf("%naaaaaaaaaaa%naaaaaaaaaaa%naaaaaaaaaaa%n",&LSB,&LSB+1,&LSB+2,&MSB);

The first %n will effectively write a zero or null byte to the return address LSB since the total number of characters printf has written at that point is zero. The second %n will print the value 11 to the second byte of the return address, the third 22, and so on. I'll leave it as an exercise for you to craft the actual buf[] payload.

Vahid
  • 301
  • 1
  • 8
  • Are you sure it's signed? I always thought it was unsigned, and unsigned stuff seems to work. Also, I know the %n way to overwrite stack stuff, but the guide I'm following says to split it up into overwriting the first 2 bytes, and then overwrite the second two. But what if you can't buff the input to the correct length because that would require buffing it to a length of 0? – robertkin Jan 22 '15 at 20:01
  • Take a look at my edited answer. Your buf array will include the characters "%n" at the beginning, which contain no null bytes and will write a zero to the desired address. – Vahid Jan 22 '15 at 22:36
  • Yes, but what if the address I want to write to contains a null byte? – robertkin Jan 23 '15 at 22:22
  • I found out how, in case any future visitors are interested. The string you pass as a parameter to the format string is also on the stack, so you can overwrite your own string so it includes null bytes before you modify other items on the stack. – robertkin Jan 23 '15 at 23:44
  • Spot on. You can write multiple null bytes using `printf("%n%n...%n",$addr1,$addr2,...,$addrN)` but of course the payload you can deliver is limited by the size of the input buffer. – Vahid Jan 26 '15 at 14:51