140 likes | 157 Views
Exploiting Format String Vulnerabilities. Paper by: Scut/team teso September 1, 2001. Presentation by: David Allen October 05, 2005. Overview. Exploit of the ANSI C format functions. Occurs when attacker can provide the format string in part or as a whole. Proper Use:
E N D
Exploiting Format String Vulnerabilities Paper by: Scut/team teso September 1, 2001 Presentation by: David Allen October 05, 2005
Overview • Exploit of the ANSI C format functions. • Occurs when attacker can provide the format string in part or as a whole. Proper Use: print_msg( char *msg ) { printf( "%s\n", msg ); } Vulnerable Use: print_msg( char *msg ) { printf( msg ); }
Attacks • Crash the program. • View stack contents. • View any process memory. • Change any process memory. • Take control of process. • Execute system commands.
Severity • Often very easy to exploit. • Can bypass protection of systems like StackGuard and StackShield. • Automated tools can find vulnerability in code. • Usually easier to exploit than buffer overflows, but also easier to find and fix.
Format Functions • Many format functions: fprintf, printf, sprintf, snprintf, vfprintf, vprintf, vsprintf, vsnprintf • Others with format strings: setproctitle, syslog, err*, verr*, warn*, vwarn*
Variable Arguments • In C, a variable number of arguments can be passed to functions. • The called function must determine the number and type of arguments. • The format string tells the format function what arguments to expect.
Stack 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. stack growth print_msg() VARARG ptr print_msg( char *msg ) { char buffer[512]; strncpy( buffer, msg, 511 ); buffer[511] = ‘\0’; printf( buffer ); } printf()
Crashing the Program 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() VARARG ptr print_msg( char *msg ) { char buffer[512]; strncpy( buffer, msg, 511 ); buffer[511] = ‘\0’; printf( buffer ); } printf()
Reading Stack Memory 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() VARARG ptr print_msg( char *msg ) { char buffer[512]; strncpy( buffer, msg, 511 ); buffer[511] = ‘\0’; printf( buffer ); } printf()
Reading Arbitrary Memory 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
Writing Arbitrary Memory 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
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.
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().
Limitations • Buffer on the heap can make the exploits more difficult. • Addresses on the stack can’t contain 0x25 (%) or 0x00 without causing problems.