Format String Vulnerability and Prevention with Example

10 Sep, 2018
A format string is an ASCII string that contains text and format parameters.
Example:
// A statement with format string
printf("my name is : %s\n", "Akash");

// Output
// My name is : Akash

There are several format strings that specify output in C and many other programming languages but our focus is on C.
Format string vulnerabilities are a class of bug that take advantage of an easily avoidable programmer error. If the programmer passes an attacker-controlled buffer as an argument to a printf (or any of the related functions, including sprintf, fprintf, etc), the attacker can perform writes to arbitrary memory addresses. The following program contains such an error:
// A simple C program with format// string vulnerability#include<stdio.h>  int main(int argc, char** argv){    char buffer[100];    strncpy(buffer, argv[1], 100);      // We are passing command line    // argument to printf    printf(buffer);      return 0;}
Since printf has a variable number of arguments, it must use the format string to determine the number of arguments. In the case above, the attacker can pass the string “%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p” and fool the printf into thinking it has 15 arguments. It will naively print the next 15 addresses on the stack, thinking they are its arguments:
$ ./a.out "%p %p %p %p %p %p %p %p %p %p %p %p %p %p %p"
0xffffdddd 0x64 0xf7ec1289 0xffffdbdf 0xffffdbde (nil) 0xffffdcc4 0xffffdc64 (nil) 0x25207025 0x70252070 0x20702520 0x25207025 0x70252070 0x20702520

At about 10 arguments up the stack, we can see a repeating pattern of 0x252070 – those are our %ps on the stack! We start our string with AAAA to see this more explicitly:
$ ./a.out "AAAA%p %p %p %p %p %p %p %p %p %p"
AAAA0xffffdde8 0x64 0xf7ec1289 0xffffdbef 0xffffdbee (nil) 0xffffdcd4 0xffffdc74 (nil) 0x41414141

The 0x41414141 is the hex representation of AAAA. We now have a way to pass an arbitrary value (in this case, we’re passing 0x41414141) as an argument to printf. At this point we will take advantage of another format string feature: in a format specifier, we can also select a specific argument. For example, printf(“%2$x”, 1, 2, 3) will print 2. In general, we can do printf(“%$x”) to select an arbitrary argument to printf. In our case, we see that 0x41414141 is the 10th argument to printf, so we can simplify our string1:
$ ./a.out 'AAAA%10$p'
AAAA0x41414141

Preventing Format String Vulnerabilities
Always specify a format string as part of program, not as an input. Most format string vulnerabilities are solved by specifying “%s” as format string and not using the data string as format string
If possible, make the format string a constant. Extract all the variable parts as other arguments to the call. Difficult to do with some internationalization libraries
If the above two practices are not possible, use defenses such as Format_Guard . Rare at design time. Perhaps a way to keep using a legacy application and keep costs down.Increase trust that a third-party application will be safe
Referenceshttps://www.owasp.org/index.php/Format_string_attackhttps://www.exploit-db.com/docs/28476.pdf
This article is contributed by Akash Sharan. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
secure-coding
vulnerability
Advanced Computer Subject
C Language
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
ML | Monte Carlo Tree Search (MCTS)
Basics of API Testing Using Postman
Copying Files to and from Docker Containers
Markov Decision Process
Getting Started with System Design
std::sort() in C++ STL
Bitwise Operators in C/C++
Arrays in C/C++
Substring in C++
Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc()