1 / 48

Buffer Overruns

Buffer Overruns. Jon Pincus Senior Researcher Systems and Networking Area Microsoft Research Microsoft Corporation. The History Of Buffer Overruns (Condensed). 1988: “The Internet Worm” (aka the Morris worm) 1996: AlephOne’s Smashing the Stack for Fun and Profit

tailynn
Download Presentation

Buffer Overruns

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Buffer Overruns Jon Pincus Senior Researcher Systems and Networking Area Microsoft Research Microsoft Corporation

  2. The History Of Buffer Overruns (Condensed) • 1988: “The Internet Worm” (aka the Morris worm) • 1996: AlephOne’s Smashing the Stack for Fun and Profit • 1997: SolarDesigner’s exploit for NX stack patch • 1998: DilDog teaches The Tao of Windows Buffer Overruns • 2000: Buffer overruns named “Bug of the decade” • 2001: Code Red; Halvar Flake: “heap overruns will be the next wave” • 2002: Slapper; heap overruns are in fact the next wave; exploits of integer overflows published in Phrack • 2003: Slammer, Blaster; Linux kernel integer overflow attack; Point-and-click exploit tools; CERT advisories for overruns on Windows, sendmail, Cisco, OpenSSL, Oracle, Sun XDR, …

  3. Agenda • Introduction • Key characteristics of buffer overruns • Spot the defect! • Defenses against buffer overruns • What is Microsoft doing?

  4. Buffer OverrunsThe problem • A buffer overrun occurs when the program attempts to write beyond the end of a bounded array (aka "buffer") • This is due to at least one defect in the code • A buffer overrun typically leads to a vulnerability • These vulnerabilities can have major consequences

  5. Exploits Take Advantage Of A Vulnerability To Accomplish A Goal • In C/C++, exploits of buffer overruns can result in elevation of privilege (EoP) • Worst case: exploitable via anonymous remote access • Worst case #1: Remotely rooting a machine • Worst case #2: Exploit + payload = worm • One way to accomplish EoP is via arbitrary code execution • In “safer” environments (Java, .NET) exploits of buffer overruns still result in Denial of Service (DoS) • May indirectly lead to EoP • Still, this is a much, much better situation

  6. Who Can Exploit Buffer Overruns? • 20th century: “Rreally smart people” • Early 00s: Competent programmer • Well-described techniques for finding, exploiting overruns • Tools starting to make life easier for exploiters • “Really smart people” continue to develop more complex exploits • Today: Script kiddies, once the patch has come out • Good tools, toolkits are available • Competent programmers can now enhance/package them • Slashdot: “Looks like a 14-year-old kid can do it” • Tomorrow: Script kiddies, preschoolers, …

  7. HistoryBuffer overrun defenses (condensed) • 1988: We all stop using gets() • 1996: strlcpy/strlcat, OpenBSD code sweep • 1997: SolarDesigner’s non-executable patch • 1998: StackGuard (stack canaries) • 1999: Grep-like analysis tools (ITS4, RATS, etc.) • 2000: More powerful static analysis tools (PREfix, splint, etc.) • 2001: PaX ASLR randomization • 2002: C-Cured, Program shepherding: promising research approaches • 2003: W^X, binary-based static-analysis tools

  8. Defenses Against Buffer Overruns • Prevention: Keep them out of the code in the first place • Examples: Better libraries, training • Detection: Find them and remove them • Examples: Code review, fuzz testing, static analysis • Mitigation: Reduce consequences of remaining ones • Typically: Crash instead of allowing code injection • Examples: Stack canaries, disable functionality by default, recode into a safer language • These are all valuable approaches … • … but there are limitations to all of them

  9. Agenda • Introduction • Key characteristics of buffer overruns • Spot the defect! • Defenses against buffer overruns • What is Microsoft doing?

  10. Three Key Characteristics Of A Buffer Overrun • What kind of memory is overrun? • How many bytes of memory are overrun? • What is the code-level defect? • Important both from an exploit and a defense perspective

  11. What Kind Of Memory Is Overrun? • 20th century • Stack buffer overruns easy to exploit by “stack smashing” • Today • Stack buffer overruns easy to exploit by many different techniques • Some heap overruns are easy to exploit by “heap smashing” • Tomorrow • Stack, heap overruns will be even easier to exploit • Shared memory, etc., will also be threats • Defense perspective: consider all kinds of memory

  12. How Many Bytes Are Overrun? • 20th century: Large overruns are usually exploitable in the wild • Typically need enough bytes for a shellcode and “no-op sled” (200+), and to clobber the saved return address • Today: Four-byte overruns are often exploitable in the wild • “All I need is an arbitrary pointer write ...” • Soon: One-byte overruns likely to be exploitable in the wild • Defense perspective: Have to worry about one-byte and up

  13. A Buffer Overrun Has Multiple Causes, Typically Including ... • One or more code-level defects • At the code level, every buffer overrun is caused by a missing, or insufficient, or incorrect check for validity of user-supplied input • Design/architecture choices • Some designs and architectures are less likely to lead to buffer overruns • Language/library choice • Some libraries (e.g., self-resizing strings) make buffer overruns less likely • Some languages (e.g., VB, Java, C#) make the consequences of buffer overruns less severe • Human fallibility • If programmers were perfect, these mistakes wouldn’t happen!

  14. What Is The Code-Level Defect? • 20th century • String function abuse • Simple bounds errors • Today • Loops • Integer overflows • Signed/unsigned mismatches, other arithmetic problems • Tomorrow: Race conditions? • Defense perspective: Have to worry about all of these • “It’s not just strcpy and strncpy any more!”

  15. Agenda • Introduction • Key characteristics of buffer overruns • Spot the defect! • Defenses against buffer overruns • What is Microsoft doing?

  16. void f(char *src1, char* src2) { char dest[DEST_SIZE]; // check to make sure first string fits if (strlen(src1) > sizeof(dest)) return; strcpy(dest, src1); // copy as much of the second string as will fit strncat(dest, src2, sizeof(dest)); ... } Spot The Defect! (1)

  17. void f(char *src1, char* src2) { char dest[DEST_SIZE]; // check to make sure first string fits if (strlen(src1) > sizeof(dest)) return; strcpy(dest, src1); // copy as much of the second string as will fit strncat(dest, src2, sizeof(dest)); ... } See Miller and deRaadt, strlcpyand strlcat Spot The Defect! (1)String function abuse strncat’s 3rd param is # of chars to copy, not the buffer size

  18. #ifdef UNICODE #define _sntprintf _snwprintf #define TCHAR wchar_t #else #define _sntprintf _snprintf #define TCHAR char #endif TCHAR buff[MAX_SIZE]; _sntprintf(buff, sizeof(buff), _T(”%s:%s...”), in1, in2); Spot The Defect! (2)

  19. #ifdef UNICODE #define _sntprintf _snwprintf #define TCHAR wchar_t #else #define _sntprintf _snprintf #define TCHAR char #endif TCHAR buff[MAX_SIZE]; _sntprintf(buff, sizeof(buff), _T(”%s:%s...”), in1, in2); Spot The Defect! (2)SI/Unicode mismatch _snwprintf’s 2nd param is # of chars in buffer, not # of bytes

  20. extern TCHAR g_szName[MAX_PATH + 1]; static const TCHAR c_szServerName[] = "SERVER_NAME"; DWORD dwSize = sizeof(g_szName); TCHAR szAnsiName[MAX_NAME_LENGTH + 1]; GetVariable (connID, c_szServerName, // variable name to get szAnsiName, // output dwSize);// size of output Spot The Defect! (3)

  21. extern TCHAR g_szName[MAX_PATH + 1]; static const TCHAR c_szServerName[] = "SERVER_NAME"; DWORD dwSize = sizeof(g_szName); TCHAR szAnsiName[MAX_NAME_LENGTH + 1]; GetVariable (connID, c_szServerName, // variable name to get szAnsiName, // output dwSize);// size of output in bytes Spot The Defect! (3)

  22. extern TCHAR g_szName[MAX_PATH + 1]; static const TCHAR c_szServerName[] = "SERVER_NAME"; DWORD dwSize = sizeof(g_szName); TCHAR szAnsiName[MAX_NAME_LENGTH + 1]; GetVariable (connID, c_szServerName, // variable name to get szAnsiName, // output dwSize);// size of output Spot The Defect! (3)Simple bounds error the wrong size is passed in: MAX_PATH + 1 instead of MAX_NAME_LENGTH + 1

  23. char buff1[MAX_SIZE], buff2[MAX_SIZE]; out = buff1; // make sure it’s a valid URL and will fit if (! isValid(url)) return; if (strlen(url) > MAX_SIZE – 1) return; // copy up to first separator do { // skip spaces if (*url != ’ ’) *out++ = *url; } while (*url++ != ’/’); strcpy(buff2, buff1); ... Spot The Defect! (4)

  24. char buff1[MAX_SIZE], buff2[MAX_SIZE]; out = buff1; // make sure it’s a valid URL and will fit if (! isValid(url)) return; if (strlen(url) > MAX_SIZE – 1) return; // copy up to first separator do { // skip spaces if (*url != ’ ’) *out++ = *url; } while (*url++ != ’/’); strcpy(buff2, buff1); ... Spot The Defect! (4)Loop termination what if there is no ‘/’ in the URL?

  25. char buff1[MAX_SIZE], buff2[MAX_SIZE]; out = buff1; // make sure it’s a valid URL and will fit if (! isValid(url)) return; if (strlen(url) > MAX_SIZE – 1) return; // copy up to first separator do { // skip spaces if (*url != ’ ’) *out++ = *url; } while (*url++ != ’/’) && (*url != 0); strcpy(buff2, buff1); ... Spot The Defect! (5)

  26. char buff1[MAX_SIZE], buff2[MAX_SIZE]; out = buff1; // make sure it’s a valid URL and will fit if (! isValid(url)) return; if (strlen(url) > MAX_SIZE – 1) return; // copy up to first separator do { // skip spaces if (*url != ’ ’) *out++ = *url; } while (*url++ != ’/’) && (*url != 0); strcpy(buff2, buff1); ... Spot The Defect! (5)Loop termination again • order of tests is wrong. • what about 0-length URLs? • buff1 is not 0-terminated

  27. void *ConcatBytes(void *buf1, size_t len1, char *buf2, size_t len2){ void *buf = malloc(len1 + len2); if (buf == NULL) return; // allocation failed memcpy(buf, buf1, len1); memcpy(buf + len1, buf2, len2); ... Spot The Defect! (6)

  28. void *ConcatBytes(void *buf1, size_t len1, char *buf2, size_t len2){ void *buf = malloc(len1 + len2); if (buf == NULL) return; // allocation failed memcpy(buf, buf1, len1); memcpy(buf + len1, buf2, len2); ... Spot The Defect! (6)Integer overflow What if: len1 == 0xFFFFFFFE len2 == 0x00000102 Then only 0x100 bytes are malloc’ed

  29. Spot The Bug On Channel 9 • Shameless plug: if you enjoyed Spot the Defect, visit Channel9 and play Spot the Bug in the TechOff forum! • http://channel9.msdn.com/ShowPost.aspx?PostID=65412 • http://channel9.msdn.com/ShowPost.aspx?PostID=55931 • http://channel9.msdn.com/ShowPost.aspx?PostID=46264

  30. Abuse of string function Simple bounds error Unicode/ANSI mismatch Loop termination Arithmetic error (e.g., integer overflow, signed/unsigned) Common Code-level Causes Of Buffer Overruns Classic “20th century buffer overruns” CodeRed Blaster A cool new name coming soon?

  31. Agenda • Introduction • Key characteristics of buffer overruns • Spot the defect! • Defenses against buffer overruns • What is Microsoft doing?

  32. Defenses Against Buffer Overruns (Recap) • Prevention: Keep them out of the code in the first place • Detection: If they’re in the code, find them and remove them • Mitigation: Reduce the consequences of the remaining ones

  33. Key Prevention Techniques • Education • Training • Better libraries • Or at least avoiding dangerous parts of existing libraries

  34. PreventionState of the art (2005) • Good books and articles exist • Good string libraries exist • Self-resizing strings for C++ (and C#, Java) • Counted strings, for C • strlcat, snprintf, and SafeStr if you really really need to deal with character arrays • Issues: Existing code, breaking old developer habits • No general approach to preventing integer overflows, etc • but see recent Integer Handling with the C++ SafeInt Class at http://msdn.microsoft.com/columns/secure.asp

  35. Detection Techniques • Code review • Issues: Imperfect, very time-consuming • Testing • “Fuzz testing” is especially useful • Issues: Incomplete coverage, “smart fuzzing” is still something of an art • Static analysis • Source-based or binary-based • Issues: Existing tools do not find all defects, “noise”

  36. DetectionState of the art (2/2004) • Making progress • There are still significant limitations • Proof by example (1): Sendmail • Code-reviewed and tested for years and years … • The test case of choice for static analysis tools ... • ... but new buffer overruns continue to be discovered • Proof by example (2): Microsoft aggressively develops and deploys static analysis tools, code review, testing, but ...

  37. Mitigation Techniques • Attack surface reduction (e.g., disabling functionality by default) • Bounds checking • Issues: Performance, compatibility • Stack canaries and stack cookies • Issues: Vulnerability to implementation-level attacks, limited to stack overruns • Heap meta-data checking, heap cookies • NX (non-executable stack/heap) and W^X • Issues: Compatibility, limited to “code injection” attacks • Randomization • Pointer encryption • Program shepherding

  38. MitigationState of the art (2005) • OS’s shipping with mitigations enabled, e.g. • Microsoft Windows Server 2003 SP1 and XPSP2 with Visual Studio /GS stack cookies, /SafeSEH exception handling checking, NX, heap checking • OpenBSD with W^X and ProPolice • Add-ons are also available: Wirex, PaX, OpenWall, ... • Effectiveness is still limited in practice

  39. Case StudyMitigations • MS03-026 was the vulnerability exploited by Blaster • Several mitigations are effective against Blaster • /GS stack cookies • non-executable stack • But other exploits of MS03-026 defeat those mitigations • LSD, NGSS, and Cigital have all discovered exploits that defeat the version of /GS used in Windows Server 2003 • X-otic has published an exploit that gets around NX • If /GS and/or NX had been widely deployed, somebody probably would have built Blaster around these more powerful exploits

  40. Agenda • Introduction • Key characteristics of buffer overruns • Spot the defect! • Defenses against buffer overruns • What is Microsoft doing?

  41. Microsoft Product Development Timeline (subset) Security push Learn and Refine Security review External review Concept / Requirements Designs Complete Test plansComplete Code Complete Ship Post Ship Training Review old defects Check-ins checked Secure coding guidelines Use static analysis, testing tools Code reviews Data mutation & Fuzz Tests Design Review

  42. Key Defense Techniques At Microsoft • Prevention: SafeStr, SafeInt<T>, Secure C Runtime, training • See Writing Secure Code, 2nd edition • Code review • At checkin time, system-wide review as part of “security push” • Developing tools to make code review more effective • Testing: Developer tests, stress tests, fuzz tests • Additional run-time checks to find “latent” buffer overruns • Static analysis: PREfix, PREfast, espX • Major effort: Adding annotations to improve tools’ effectiveness • Mitigations: /GS, NX, “secure by default”

  43. But We’re Obviously Not Perfect … • Any “MSRC-class” defect reveals multiple failures, e.g. • Code review missed the defect • Static analysis missed the defect • Testing/fuzzing missed the defect • We do a root cause analysis focused on two major questions • Why did these failures occur? • How to improve?

  44. Sample Analyses And Action Items • Training did not cover the coding construct • Immediately: Add it to training (duh) • Short term: Look for other coding constructs that may be overlooked • Code reviewers missed the defect • Immediately code review all code for this and similar defects • Longer term: Look at how to improve code reviews in general • Static analysis tools missed the defect due to known limitations • Immediately introduce some new “very-high-noise” warnings into tools, and run revised tools on entire code base • Longer term: Continue work (already in progress) on new analyses that can find this problem with low noise

  45. Conclusion • Attackers are improving • “Anybody can do it!” • Cleverer exploits • Defenses are improving too, in several dimensions • Prevention, detection, mitigation • Our goal: get to the point where buffer overruns are no longer the most critical security-related defects

  46. Buffer Overruns Jon Pincus Senior Researcher Systems and Networking Area Microsoft Research Microsoft Corporation

  47. © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

More Related