To understand what a format string vulnerability is, you first need to know what a format string is. A format string is a way of telling the C compiler how it should format numbers when it prints them.
Format Strings in C
In the C programming language there are a number of functions which accept a format string as an argument. These functions include fprintf, printf, sprintf, snprintf, vfprintf, vprintf, vsprintf, vsnprintf, setproctitle, syslog, and others.
The most common of these is printf. The usage of printf is:
printf format [arguments …]
printf outputs the value of [arguments …] in the format specified by format.
An example call to printf is:
printf (“The area code is: %dn”, 303);
Supported format specifiers differ from one C compiler to the next. The format specifiers supported under FreeBSD are:
%d Convert integer to signed decimal string. %u Convert integer to unsigned decimal string. %i Convert integer to signed decimal string; the integer may either be in decimal, in octal (with a leading 0) or in hexadecimal (with a leading 0x). %o Convert integer to unsigned octal string. %x or %X Convert integer to unsigned hexadecimal string, using digits “0123456789abcdef” for x and “0123456789ABCDEF” for X). %c Convert integer to the Unicode character it represents. %s No conversion; just insert string. %f Convert floating-point number to signed decimal string of the form xx.yyy, where the number of y’s is determined by the precision (default: 6). If the precision is 0 then no decimal point is output. %e or %E Convert floating-point number to scientific notation in the form x.yyye+-zz, where the number of y’s is determined by the precision (default: 6). If the precision is 0 then no decimal point is output. If the E form is used then E is printed instead of e. %g or %G If the exponent is less than -4 or greater than or equal to the precision, then convert floating-point number as for %e or %E. Otherwise convert as for %f. Trailing zeroes and a trailing decimal point are omitted. %% No conversion: just insert %.
For more information on format specifiers, refer to the man page for “format” on your nearest Unix system.
Format String Vulnerability Attacks
Format string vulnerability attacks fall into three categories: denial of service, reading and writing.
- Format string vulnerability denial of service attacks are characterized by utilizing multiple instances of the %s format specifier to read data off of the stack until the program attempts to read data from an illegal address, which will cause the program to crash.
- Format string vulnerability reading attacks typically utilize the %x format specifier to print sections of memory that we do not normally have access to.
- Format string vulnerability writing attacks utilize the %d, %u or %x format specifiers to overwrite the Instruction Pointer and force execution of user-supplied shell code.