Security Lab Episode 6: Format String Vulnerabilities Jan Nordholz, Matthias Petschick, Julian Vetter Prof. Jean-Pierre Seifert Security in Telecommunications TU Berlin SoSe 2015 jan, matthias, julian (sect) Security Lab SoSe 2015 1 / 13
Glue Slide Recalling: buffer overflows often allow redirecting the flow of execution and jumping to custom shellcode. So far we discussed how to write machine code and execute it as part of a BOF exploit. This week: a look at another bug class, namely Format String vulnerabilities. jan, matthias, julian (sect) Security Lab SoSe 2015 2 / 13
What is a format string? Used to convert datatypes to a string representation (very primitive pretty printer). Example printf prototype: int printf(const char *restrict format,...); e.g. printf( Your %dst name is %s, 1, Foobar ); Your 1st name is Foobar format points to a supplied format string (a pretty print recipe )... indicates a variable number of arguments ( variadic function, see man 3 va arg) Prominent functions that accept format strings: {s,sn,vs,vsn,f,}printf; {f,s,}scanf; syslog... jan, matthias, julian (sect) Security Lab SoSe 2015 3 / 13
What are common format conversion specifiers? There is a large set of conversion specifiers (see man 3 printf)! A few examples: specifier conversion output passed as %c single character value %s null-terminated string pointer %d signed integer value %u unsigned integer value %p pointer value value %x hexadecimal value jan, matthias, julian (sect) Security Lab SoSe 2015 4 / 13
Processing of format strings: the big picture jan, matthias, julian (sect) Security Lab SoSe 2015 5 / 13
Processing of format strings: the big picture with own arguments without own arguments jan, matthias, julian (sect) Security Lab SoSe 2015 5 / 13
Processing of format strings (3): the close-up Remember the calling convention! x86 expects arguments on the stack, ARM uses registers (at least for the first ones) and the stack So for each argument specified by the format string, libc accesses the next appropriately-sized chunk of memory (or register data) provided by the calling function... No matter whether it has actually filled that space with arguments or not! jan, matthias, julian (sect) Security Lab SoSe 2015 6 / 13
So what is a Format String Vulnerability? Fairly new bug class, initially explored in 1999/2000. Let s start with a simple example: Example: void swallow egg(char *ptr) { char buf[32]; strncpy(buf, ptr, sizeof(buf)); buf[sizeof(buf)-1] = 0; printf(buf); } Let s assume ptr references an attacker-controlled string! Format string is attacker-controlled as well! jan, matthias, julian (sect) Security Lab SoSe 2015 7 / 13
Format String Vulnerability Implications (1) Possibility to read values from the top of the stack printf( %x%x%x%x ); prints the last 4 words on the stack in hexadecimal Can be used to leak secret data (%s, %x,..), pointers etc. Perform DoS attacks: e.g. %s%s%s%s%s may dereference an invalid pointer Crash Example: int main(int ac, char **av) { printf(av[1]); } $./a.out "%p.%p.%p.%p.%p" 0xbfb95650.0xbfb956a8.0xb75dc455.0x80483f0.0x80482f0 jan, matthias, julian (sect) Security Lab SoSe 2015 8 / 13
Format String Vulnerability Implications (2) Reading memory is nice, but what about writing? Enter the one conversion specificer that writes to memory: %n! %n stores the number of bytes written so far into the supplied pointer argument. There are almost no sensible applications for this beast, so MS apparently disabled it in the mid-2000s (one good decision). Anyway, it s still around on Unix! Idea: discover useful pointer values (%x) and abuse them (%n)! jan, matthias, julian (sect) Security Lab SoSe 2015 9 / 13
Abusing Format Strings (1) Once more the simple swallow egg() example: void swallow egg(char *ptr) { char buf[32]; strncpy(buf, ptr, sizeof(buf)); printf(buf); } jan, matthias, julian (sect) Security Lab SoSe 2015 10 / 13
Abusing Format Strings (2) Unix printf() has yet more features (some of them GNU extensions)! Direct argument access %j$x applies the %x conversion to the j-th argument Not available in uclibc (used on the pandaboard) Integer width modifiers allows reading/writing 1, 2, 4 or 8 byte values (%hhi, %hi, %li, %lli) Note: this works even with %n! Length and precision attributes (%.8f, %32s) Helpful in tuning the current number of written characters to a desired value So in order to write an arbitrary 4 byte value, write it incrementally (4x1 byte using %hhn or 4x4 bytes partially overlapping each other) jan, matthias, julian (sect) Security Lab SoSe 2015 11 / 13
Abusing Format Strings (3) In order to use %n effectively, you need useful pointer values you can feed to it Often, the printf() buffer itself is on the stack and thus available as argument space to format conversions include necessary pointers in your attack input, then use %n on them Last resort: place your pointer values into the environment! The environment is always on the stack, and its distance to the top of the stack is usually constant for a single bug jan, matthias, julian (sect) Security Lab SoSe 2015 12 / 13
Student Assignment Install the new SD card images (yes, yet again)... Give the mediacenter service a close look. Maybe connect a storage device? (Note you can reuse the SD card for this, the system resides completely in RAM.) Note: It s probably easiest to do this challenge completely on the board. The mediacenter service has inotify support and the SD card is mounted r/w for anyone. One last hint: It may not be necessary to hijack control flow. Look at the functionality provided by mediacenter. There is an easier way to get a shell! jan, matthias, julian (sect) Security Lab SoSe 2015 13 / 13