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?
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()
).