APPLE GOTO FAIL BUG CVE-2014-1266 (See https://cve.mitre.org/cgi-bin/ cvename.cgi?name=CVE-2014-1266) What: does not check the signature in TLS Server Key Exchange message Consequences: allows man-in-the-middle attackers to: - spoof SSL servers by: (1) using an arbitrary private key for the signing step or (2) omitting the signing step. Affected Apple iOS 6.x before 6.1.6 ... APPLE'S PUBLISHED SOURCE CODE static OSStatus SSLVerifySignedServerKeyExchange( SSLContext *ctx, bool isRsa, SSLBuffer signedParams, uint8_t *signature, UInt16 signatureLen) { OSStatus err; ... if ((err = SSLHashSHA1.update( &hashCtx, &serverRandom)) != 0) goto fail; if ((err = SSLHashSHA1.update( &hashCtx, &signedParams)) != 0) goto fail; goto fail; if ((err = SSLHashSHA1.final( &hashCtx, &hashOut)) != 0) goto fail; // ...more validation ... fail: SSLFreeBuffer(&signedHashes); SSLFreeBuffer(&hashCtx); return err; } STATIC DETECTION OF GOTO-FAIL BUG? DYNAMIC DETECTION OF GOTO-FAIL BUG? HEARTBLEED Vulnerability of OpenSSL Used often in implementations of SSL/TLS IMPACT OF HEARTBLEED "Heartbleed affected a huge number of popular websites, including: - Google, - YouTube, - Yahoo!, - Pinterest, - Blogspot, - Instagram, - Tumblr, - Reddit, - Netflix, - Stack Overflow, - Slate, - GitHub, - Yelp, - Etsy, - the U.S. Postal Service (USPS), - Blogger, - Dropbox, - Wikipedia, - the Washington Post." Source: dwheeler.com/essays/heartbleed.html KEEP-ALIVE FEATURE IN SSL Protocol client: sends arbitrary data to server server: sends back an exact copy Message format (in C): struct { HeartbeatMessageType type; uint16 payload_length; opaque payload [HeartbeatMessage.payload_length]; opaque padding[padding_length]; } HeartbeatMessage; Sent via SSL3_RECORD: struct ssl3_record_st { unsigned int length; unsigned char *data; } SSL3_RECORD; FROM CODE OF OPENSSL tlsl_process_heartbeat(SSL *s) { unsigned char *p = /*...*/, *pl; unsigned short hbtype; unsigned int payload, padding = 16; /* ... */ /* Read type and payload length first */ hbtype = *p++; /* p points to message */ /* write the 16-bit length into payload and adds 2 bytes to p.*/ n2s(p, payload); pl = p; /* pl points to payload contents */ /* ... */ if (hbtype == TLS1_HB_REQUEST) { /* Contruct reply */ unsigned char *buffer, *bp; buffer = OPENSSL_malloc(1+2+payload+padding); bp = buffer; /* bp points to reply */ *bp++ = TLS1_HB_RESPONSE; s2n(payload, bp); memcpy(bp, pl, payload); } } WHAT IS THE PROBLEM? Buffer over-read (CVE-126) reading past end of buffer Improper input validation (CVE-20) WHY WASN'T HEARTBLEED DETECTED EARLIER? The code is complex: - indirection - special memory allocation Static tools are often incomplete - heuristics can miss bugs Dynamic tools used: - mostly positive tests - code coverage - fuzzers in traditional way WHAT COULD HAVE PREVENTED HEARTBLEED? (from dwheeler.com/essays/heartbleed.html) static: 1. making code simple enough for static analysis tools 1a. Taint analysis checking when inputs are used without being sanitized dynamic: 2. thorough negative testing (testing inputs that should fail) 3. fuzz testing with address checking Address sanitizer is an extra flag (-fsanitize=address) in LLVM,clang,gcc 4. Other address access detection tools - Binary simulator (Valgrind, Dr. Memory) - Guard pages (OS page faults) static: 5. Focused manual spot-checks - check that every field used is validated dynamic: 6. Fuzzing with output examination static: 7. Formal methods - specify code behavior and check it using a verifier hybrid: 8. Fuzz test several implementations at 100% branch coverage dynamic: 9. Runtime assertion checking static: 10. Use a safer programming language 11. Thorough human review DIRTY COW Local privilege escalation - use a race condition in Copy-on-write mechanism. - can lead to remote execution Attack: 1. Open a root-writable, world-readable file read-only 2. Do the same in 2 (or more) threads 3a. Some thread(s) call madvise(..., MADV_DONTNEED) - so OS tries to unload the file 3b. Some thread(s) try to write file 4. Bug in OS causes it to (sometimes) ignore that the file is read-only HOW TO DETECT CONCURRENCY BUGS? Static analysis: - large number of false positives - Precise only for simple locking disciplines Dynamic analysis: - Instrument source code, check lockset and happens before - Try different inputs and scheduler combinations to search for race(s)