4

In the paper Exploiting Format String Vulnerabilities the authors give the following code sample where input is some unfiltered user input.

char outbuf[512];
char buffer[512];
sprintf (buffer, "ERR Wrong command: %400s", input);
sprintf (outbuf, buffer);

They then explain that by using a special format string as input they can bypass the %400s limitation:

"%497d\x3c\xd3\xff\xbf<nops><shellcode>"

This creates a string which is 479 characters long. However, I can't find an explaination for how %479d bypasses the %400s limitation. How does this input enable sprintf to write a string which is longer than 400 characters?

2 Answers2

3

The second sprintf() overflows outbuf because it uses a format string generated by the first sprintf(), and placing "%497d" in that string makes it print a 497-char wide integer field (padded with spaces to get the full width). This along with the rest of that string, would exceed the 512-char outbuf buffer size. It would also make it try to read an integer argument that's not actually passed to the function (2nd sprintf()).

Dmitri
  • 9,175
  • 2
  • 27
  • 34
0

The problem is that if input contains % markers, then buffer will contain those % markers (after the first sprintf()), and then using the second sprintf(), the 'format string' is buffer and the % markers in it will be interpreted, even though there are no arguments to interpolate into outbuf. To avoid the problem:

snprintf(outbuf, sizeof(outbuf), "%s", buffer);

or

strcpy(outbuf, buffer);

In this context, snprintf() is overkill, but it is stripping the mechanism down to basics.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278