Check Your Inputs Petr Ročkai Trusted Input • data that comes with the program • signed data bundles and similar • (maybe) data provided by the user • system resources (fonts, icons, ...) Untrusted Input • everything else Check Your Inputs 1/39 September 25, 2017 Things to Check • size of input data vs buffer bounds • integer under- and overflows • signed/unsigned mismatches • special characters and escaping Check Your Inputs 2/39 September 25, 2017 Trusted vs Untrusted Mismatch • many parsers were written to only deal with trusted data • increasingly, data comes in from untrusted 3rd parties - JPEG (CVE-2004-0200, CVE-2016-4635, -8332,...) - Web Fonts (CVE-2006-0010, CVE-2011-3402, ...) - MIDI files from the Internet (CVE-2012-0003) - PDF files (CVE-2010-3636, CVE-2015-0816,...) - various other music, video, etc. formats • when in doubt, validate everything Check Your Inputs 3/39 September 25, 2017 Part 1: Buffer Overflows (recap) Check Your Inputs 4/39 September 25, 2017 The C Stack int f() { int a, b; -» compute ( &a, &b ); return a + b; } int main() { int y; f 0; Check Your Inputs 5/39 September 25, 2017 Stack Overflow • immediate arbitrary code execution • overwrite the return address Check Your Inputs 6/39 September 25, 2017 Example: Morris Worm • November 1988 • a self-replicating program • propagated across networks (internet!) • multiple exploits against known vulnerabilities • buffer overflows (e.g. f ingerd used gets) • man gets: never use gets() Check Your Inputs 7/39 September 25, 2017 Mitigation: Stack Guard • enabled with -f stack-protector in gcc (often default on) • store a randomised canary before the return address • check the value is intact in the function epilogue (before ret) • makes buffer overflows much harder to exploit Check Your Inputs 8/39 September 25, 2017 Part 2: SQL & Code Injection Check Your Inputs 9/39 September 25, 2017 HI, THI5 IS YOVR SONS 5CHCOL VE"RE HAVING SOME CoriPUTE^ trouble:. OH, DWR - DO HE BREAK SOMETTHirJG? DID you REALLY 1WETOUR SON Rcbrrt^ DROP oh, yes UT7l£ bobby TABLES, we CALL HiM^ WEl^WEVELOSTTHJS I HOPE VPL/RE WW AMD I HOPE Check Your Inputs 10/39 September 25, 2017 Vulnerable Code: sql = "SELECT * FROM t WHERE name = '" + name + "' Never, ever construct SQL this way • same goes for generating any other program fragments • including HTML, javascript, etc. • always escape user inputs Check Your Inputs 11/39 September 25, 2017 HTML, JavaScript &c. • websites often allow users to leave comments • those comments are then shown on the website • the comments are untrusted inputs • could contain fragments of malicious HTML or JavaScript Nice website you got there! Check Your Inputs 12/39 September 25, 2017 Mitigation: Blacklists • blacklist (forbid) suspect characters • filter them out or reject the entire input • eg. <, > in HTML • quotes and double quotes in SQL • backticks in shell code Error-prone & not recommended. Check Your Inputs 13/39 September 25, 2017 Mitigation: Whitelists • only allow inputs of specified form • e.g. only alphanumeric characters (user names) • numbers, spaces, dashes and + for phone numbers • alphanumeric + @ + dots, dashes &c. for e-mail addresses Better than blacklists • useful in multi-layer defence • not suitable as the sole mitigation Check Your Inputs 14/39 September 25, 2017 Mitigation: Escaping • this is the correct approach • all user input goes through an escape function • mysql_real_escape_st ring • HTML encoding using entities (< -> <) Input tainting can enforce escaping. Check Your Inputs 15/39 September 25, 2017 Mitigation: Prepared Statements • many SQL drivers, ODBC, ... • security-wise equivalent to escaping • often better performance sql = prepare( "SELECT * FROM u WHERE name = ?" ); sql.bind( 1, name ); sql.execute( connection ); Often easier to get right than manual escaping. Check Your Inputs 16/39 September 25, 2017 Part 3: Integer Overflows Check Your Inputs 17/39 September 25, 2017 Reading Integers • the integer may not fit the variable type • parsing as signed but using as unsigned Using Integers • underflow: subtracting from unsigned integers (2u - 3 = 231) • overflow: multiplication by a constant, addition • could produce bogus offsets (bigger than buffer size) • or defeat length checks in subsequent code Check Your Inputs 18/39 September 25, 2017 Exploitable Code unsigned items = atoi( argv[l] ); int *memory = (int *) malloc( items * sizeof(int) ); for ( unsigned i = 0; i < items; ++ i ) memory[i] = /* ... */ What happens if a rgv[l] is 231? Check Your Inputs 19/39 September 25, 2017 Overflow via Addition • similar as before unsigned items = atoi( argv[l] ); char *memory = malloc( items + sizeof( Header ) ); for ( unsigned i = 0; i < items; ++ i ) memory[i] = /* ... */ What if items + sizeof (Header) overflows? Check Your Inputs 20/39 September 25, 2017 CVE-2004-0200 • the JPEG parser in GDI+ in Windows • each field in the JPEG header has a 2 byte ID • the parser does a memcpy of the header data • the copy size is computed as size - 2 • size is unsigned and could be 1 or 0 • underflow -> huge (4GiB) copy • overwrites memory with the data from the JPEG file • including the unhandled exception filter pointer -> arbitrary code execution Check Your Inputs 21/39 September 25, 2017 CVE-2012-0003 • the MIDI file parser in Windows • another integer manipulation bug • the code allocates a 1024 byte buffer • can be tricked to write up to 1088 bytes -> arbitrary code execution (again) Check Your Inputs 22/39 September 25, 2017 Part 4: Format Strings Check Your Inputs 23/39 September 25, 2017 Format Strings: printf • the C function printf provides formatted output • never allow the format string to come from untrusted sources • controlling the format string is an attack vector • see man 3 printf Consequences • info leaks (may defeat ASLR, Stack Guard) • stack memory corruption Check Your Inputs 24/39 September 25, 2017 Vulnerable Code: printf( "you said:" ); printf( input ); The format string: • %[flags][width][.prec]{mod}type printf( "%s: %d", string, number ); • what to print comes from variadic arguments • those live in stack memory Check Your Inputs 25/39 September 25, 2017 Simple crash (Denial of Service) • provide "%s%s%s%s%s%s%s%s%s" to the program • will very likely try to dereference an invalid pointer • the program crashes • not a very interesting attack Check Your Inputs 26/39 September 25, 2017 Leak of Stack Data (Info Leak) • provide "%08x %08x %08x %08x\n" • dumps 16 bytes of stack data • nicely formatted, too: - e32a6ea8 e32a6eb8 00000000 56da6300 • could leak a return address (bad for ASLR) • could leak the stack canary (bad for Stack Guard) • deadly when combined with a buffer overrun Check Your Inputs 27/39 September 25, 2017 Non-Stack Data Leak • needs a stack-allocated, attacker controlled format string • provide the desired address inside the format string • give enough %x specifiers to read into the format string • finish off with a %s - M\xl0\x01\x48\x08 %x %x %s" printf arg: &fmt 8 bytes fmt[1..4] = 0x10014808 fmt[5...] = %x%x%s Check Your Inputs 28/39 September 25, 2017 Corrupting the Stack • printf conveniently provides a write operation • %n: takeanint * argument and write number of chars printed ■ 1; printf( llabcd%n"f &i ); assert( i == 4 ); If the format string is on the stack • this becomes extremely powerful (cf. previous slide) • targeted corruption -> arbitrary code execution • bundled info leak: may defeat ASLR, Stack Guard Check Your Inputs 29/39 September 25, 2017 More Format Strings • printf is not the only vulnerable function • think syslog(3) orsprintf(3) • user- or library-provided functions • those could call vsprintf (3) and similar internally • sprintf can overflow a buffer as a bonus Check Your Inputs 30/39 September 25, 2017 Mitigation: -Wformat • enable -Wformat and maybe -Wformat-nonliteral • possibly also -Werror • prevents many vulnerabilities related to format strings • unfortunately not foolproof Check Your Inputs 31/39 September 25, 2017 Part 5: Various Check Your Inputs 32/39 September 25, 2017 URL Attacks • ensure authenticated commands are not available publicly • make sure you don't leave in debug functionality • validate all arguments https://app.com/upload?target=/tmp/evil.sh https://app.com/run?program=/tmp/evil.sh https://app.com/login?auth_server=auth.attacker.com Check Your Inputs 33/39 September 25, 2017 Directory Traversal • file paths on input can be an attack vector • say your app uses render. php?page=blog/weekend. md • what happens if i call render. php?page=/etc/passwd • info leaks at very least • possibly compromise of secret (key) data • arbitrary code execution at worst CVE-2017-7240 -> a vulnerable dishwasher (!) Check Your Inputs 34/39 September 25, 2017 Environment Variables: Id. so • LD_LIBRARY_PATH • LD_PRELOAD Also PATH • pretty bad if controlled by an attacker • but also including'.' might be dangerous Check Your Inputs 35/39 September 25, 2017 Shellshock • more environment variable fun • bash parses environment variables for function definitions • accidentally executes commands coming after a function • CGI allows the attacker to set environment variables • CGI scripts that run in bash or use system () are vulnerable • no matter how careful you were otherwise Check Your Inputs 36/39 September 25, 2017 SUID Binaries • all user input is untrusted • http://insecure.org/sploits/XKB.insecurity.html • the X server used to be SUID root • and instructed via -xkbdir to run arbitrary code -> local root exploit Check Your Inputs 37/39 September 25, 2017 Fuzzing • generate (semi-)random inputs for the program • often by mutating a known-good input • run many test cases, trying to induce a crash • a crash may be indicative of a security problem • buffer overflows, double free, heap corruption, etc. • many of those are very severe (arbitrary code execution) Check Your Inputs 38/39 September 25, 2017 Homework • write an example program with an integer overflow (2pt) • use the overflowing number as an alloca parameter • this introduces a stack-based vulnerability • use your knowledge about stack exploits from first week • provide a file with input that exploits the vulnerability (2pt) • compile your code without ASLR, stack guard, etc. • use return address overwrite in your exploit (2pt) • write a text message explaining what you did (—2 pages) • also describe how to fix the vulnerability you introduced Check Your Inputs 39/39 September 25, 2017