Download presentation
Presentation is loading. Please wait.
Published byFrancine Henry Modified over 9 years ago
1
CS390S, Week 4: Format String Vulnerabilities & Integer Overflows Pascal Meunier, Ph.D., M.Sc., CISSP January 31, 2007 Developed thanks to the support of Symantec Corporation, NSF SFS Capacity Building Program (Award Number 0113725) and the Purdue e-Enterprise Center Copyright (2004) Purdue Research Foundation. All rights reserved.
2
Format String Issues: Outline Introduction to format strings Fundamental "C" problem Examples Definition Importance Survey of unsafe functions Case study: analysis of cfingerd 1.4.3 vulnerabilities Preventing format string vulnerabilities without programming Tools to find string format issues
3
What is a Format String? Encode where and how to print variables Python example: >>> print "Mary has %d lambs" % (3) Mary has 3 lambs %d specifies a decimal number (from an int) %s would specify a string argument, %X would specify an unsigned uppercase hexadecimal (from an int) etc...
4
Fundamental "C" Problem No way to count arguments passed to a "C" function, so missing arguments are not detected printf(const char *format,...); printf(“Mary has %d cats”, cats); What happens if the following code is run? int main () { printf("Mary has %d cats"); return 0; }
5
Result %./a.out Mary has -1073742416 cats Format string is interpreted: it mixes code and data Program reads missing arguments off the stack! –And gets garbage (or interesting stuff if you want to probe the stack)
6
Probing the Stack Read values off stack Confidentiality violations printf(“%08X”) x (X) is unsigned hexadecimal 0: with ‘0’ padding 8 characters wide: ‘0XAA03BF54’ 4 bytes = pointer on stack, canary, etc...
7
User-specified Format String What happens if the following code is run, assuming there always is an argument input by a user? int main(int argc, char *argv[]) { printf(argv[1]); exit(0); } Try it and input "%s%s%s%s%s%s%s%s%s" How many "%s" arguments do you need to crash it?
8
Result %./a.out "%s%s%s%s%s%s%s" Bus error Program was terminated by OS –Segmentation fault, bus error, etc... because the program attempted to read where it wasn't supposed to User input is interpreted as string format (e.g., %s, %d, etc...) Anything can happen, depending on input! How would you correct the program?
9
Corrected Program int main(int argc, char *argv[]) { printf(“%s”, argv[1]); exit(0); } %./a.out "%s%s%s%s%s%s%s" %s%s%s%s%s%s%s
10
Format String Vulnerabilities Discovered relatively recently ~2000 Limitation of “C” family languages Effects –Can affect various memory locations –Can be used to create buffer overflows –Can be used to read the stack Not straightforward to exploit, but examples of root compromise scripts are available on the web –"Modify and hack from example"
11
Definition of a Format String Vulnerability A call to a function with a format string argument, where the format string is either: –Possibly under the control of an attacker –Not followed by the appropriate number of arguments As it is difficult to establish whether a data string could possibly be affected by an attacker, it is considered very bad practice to place a string to print as the format string argument. –Sometimes the bad practice is confused with the actual presence of a format string vulnerability
12
How Important Are Format String Vulnerabilities? Search NVD (icat) for “format string”: –115 records in 2002 –173 total in April 2004 –363 in February 2006 –460 in January 2007 (~100/year) Various applications –Databases (Oracle) –Unix services (syslog, ftp,...) –Linux “super” (for managing setuid functions) –cfingerd CVE-2001-0609 Arbitrary code execution is a frequent consequence
13
Functions Using Format Strings printf - prints to"stdout" stream fprintf - prints to stream warn - standard error output err - standard error output setproctitle - sets the invoking process's title sprintf(char *str, const char *format,...); –sprintf prints to a buffer –What’s the problem with that?
14
Sprintf Double Whammy format string AND buffer overflow issues! Buffer and format string are usually on the stack Buffer overflow rewrites the stack using values in the format string
15
Better Functions Than sprintf Note that these don't prevent format string vulnerabilities: –snprintf(char *str, size_t size, const char *format,...); sprintf with length check for "size" –asprintf(char **ret, const char *format,...); sets *ret to be a pointer to a buffer sufficiently large to hold the formatted string (note the potential memory leak).
16
Write Anything Anywhere "%n" format command “Count these characters %n” Writes a number to the location specified by argument on the stack –Argument treated as int pointer Often either the buffer being written to, or the raw input, are somewhere on the stack –Attacker controls the pointer value! –Writes the number of characters written so far Keeps counting even if buffer size limit was reached! All the details you don't really need to know: –Newsham T (2000) "Format String Attacks"
17
Format Strings Summary parameteroutputpassed as %ddecimal (int)value %uunsigned decimal (unsigned int)value %xhexadecimal (unsigned int)value %sstring ((const) (unsigned) char *)pointer %nnumber of bytes written so far, (* int)pointer
18
Stack stack top … Argument: Return for print_msg() … … Argument: Return for printf() … Locals for printf() … Stack from the perspective of printf() in the following code. Since there are no variable arguments, any attempt to access them will result in access to stack memory above the printf() stack frame. print_msg( char *msg ) { char buffer[512]; strncpy( buffer, msg, 511 ); buffer[511] = ‘\0’; printf( buffer ); } VARARG ptr print_msg() printf() stack growth
19
Crashing the Program stack top … Argument: Return for print_msg() … … Argument: Return for printf() … Locals for printf() … The program can be crashed by passing in a string like: “%s%s%s%s%s%s%s%s%s%s %s” Since this causes values on the stack to be treated as pointers to strings, there is a good chance that an invalid pointer will be accessed. print_msg( char *msg ) { char buffer[512]; strncpy( buffer, msg, 511 ); buffer[511] = ‘\0’; printf( buffer ); } VARARG ptr print_msg() printf()
20
Reading Stack Memory stack top … Argument: Return for print_msg() … … Argument: Return for printf() … Locals for printf() … An attacker can read stack memory with a string like this: “%08x %08x %08x %08x %08x” Each stack word above the printf() stack frame will be printed in hexidecimal. Given a large enough buffer, potentially all of stack memory can be retrieved. print_msg( char *msg ) { char buffer[512]; strncpy( buffer, msg, 511 ); buffer[511] = ‘\0’; printf( buffer ); } VARARG ptr print_msg() printf()
21
Reading Arbitrary Memory stack top … Argument: Return for print_msg() … 0%_x 80%x 80%_ AAAA … Argument: … Notice that in this case the buffer is on the stack. If the buffer contains something like: “AAAA_%08x_%08x…|%s” Then we can move the vararg pointer until it points to the address represented by “AAAA” ( which is 0x41414141), then the %s will display memory at that address. VARARG ptr
22
Writing Arbitrary Memory stack top … Argument: Return for print_msg() … 0%_x 80%x 80%_ AAAA … Argument: … Using a similar approach we can modify memory with the %n flag. If the buffer contains something like: “AAAA_%08x_%08x…%n” Then we can move the vararg pointer until it points to the address represented by “AAAA” ( which is 0x41414141), then the %n will write the current count of bytes written to that address. VARARG ptr
23
Writing Arbitrary Memory The count can be incremented with commands line %nu where n is a small integer. X86 is little endian, so sequential bytes can be written by providing pointers in the buffer that are each incremented by one. Only the least significant byte matters, so arbitrary values can be written.
24
Exploits Update return pointer on stack to point at code stored in buffer. Update GOT (Global Offset Table) pointer to point at code stored in buffer. Write code on heap and use above methods to run it. Update GOT pointer of function like fopen() to pointer for system().
25
Limitations Buffer on the heap can make the exploits more difficult. Addresses on the stack can’t contain 0x25 (%) or 0x00 without causing problems.
26
Preventing Format String Vulnerabilities 1) Always specify a format string 1)Most format string vulnerabilities are solved by specifying "%s" as format string and not using the data string as format string 2) If possible, make the format string a constant 1)Extract all the variable parts as other arguments to the call 2)Difficult to do with some internationalization libraries 3)Use compiler switches, code scanners and run- time defenses 4)Be wary of calling C libraries from other languages
27
Code Scanners Pscan searches for format string functions called with the data string as format string –Can also look for custom functions Needs a helper file that can be generated automatically –Pscan helper file generator at http://www.cerias.purdue.edu/homes/pmeunier/dir_pscan.html –Few false positives http://www.striker.ottawa.on.ca/~aland/pscan/
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.