250 likes | 429 Views
Implementation Flaws. Part 1: Buffer Overruns. Outline. Background Three generations of flaws Classic stack smashing Off-by-one errors Format string bugs and heap overruns Mitigation Coding practices Memory protection. Background. What are buffer overruns?
E N D
Implementation Flaws Part 1: Buffer Overruns
Outline • Background • Three generations of flaws • Classic stack smashing • Off-by-one errors • Format string bugs and heap overruns • Mitigation • Coding practices • Memory protection SY32 Secure Computing, Lecture 13
Background • What are buffer overruns? • Program allocates a contiguous chunk of memory of fixed size to store data (a buffer) • Amount of data copied to buffer exceeds its capacity and overwrites other memory • Why are they a problem? • Many critical programs are written in C/C++… • …but C/C++ have no run-time bounds checking SY32 Secure Computing, Lecture 13
Background • Problem known about since 1960s • First seen widely in 1988 (Morris worm) • Infamous overruns: • wu-ftpd • Several overruns discovered in 1999 & 2000 • Some flaws up to 10 years old! • Code Red worm • Exploited buffer overrun in IIS • 359,000 machines infected within 14 hours • Estimated worldwide cost of $2 billion SY32 Secure Computing, Lecture 13
Public Enemy #1! SY32 Secure Computing, Lecture 13
Public Enemy #1! SY32 Secure Computing, Lecture 13
Possible Outcomes • No effect on program • Unpredictable behaviour (D) • Program crashes (D) • Attack affects flow of execution (T,I,D) • Attacker executes arbitrary code (T,I,D,E) SY32 Secure Computing, Lecture 13
Memory Layout: A Reminder Highmemory • Text segment holds program instructions (read-only) • Data and BSS segments provide storage for static/global data • Stack and heap change size as program executes • Stack holds information about context of function calls in a stack frame • Function parameters • Local variables • Saved register information • Return address for call Env. variables Stack Heap BSS Data Text Lowmemory SY32 Secure Computing, Lecture 13
Stack Smashing High memory Caller’sstack frame …and overwrites return address, gaining control of execution! Parameters Return address Saved frame pointer Frame pointer Other localvariables Attacker overruns buffer… Buffer Low memory Stack pointer SY32 Secure Computing, Lecture 13
Demo SY32 Secure Computing, Lecture 13
Crafting an Exploit jmp 0x1fpopl %esimovl %esi,0x8(%esi)xorl %eax,%eaxmovb %eax,0x7(%esi)movl %eax,0xc(%esi)movb $0xb,%almovl %esi,%ebxleal 0x8(%esi),%ecxleal 0xc(%esi),%edxint $0x80xorl %ebx,%ebxmovl %ebx,%eaxinc %eaxint $0x80call -0x24.string \"/bin/sh\" Shellcode void exploit(){ char* s = "/bin/sh"; execl(s, s, 0x0);}int main(){ exploit();} Must rewrite to remove nulls,or strcpy won’t work! SY32 Secure Computing, Lecture 13
Crafting an Exploit "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07 \x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d \x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80 \xe8\xdc\xff\xff\xff/bin/sh" No-ops Shellcode Addresses Address chosen to ensure jump into no-ops at start of shellcode "\x90\x90..." "\x58\x6f\xff\xbf..."(0xbffff658) SY32 Secure Computing, Lecture 13
Demo SY32 Secure Computing, Lecture 13
Questions • Are very small buffers susceptible to attack? • By how much must we overrun a buffer to execute shellcode? SY32 Secure Computing, Lecture 13
Off-By-One Errors void doSomething(const char* input){ char buffer[256]; strncpy(buffer, input, sizeof(buffer)); buffer[sizeof(buffer)] = '\0'; ...} • Sensible choice of strncpy in place of strcpy • …but attempt to null-terminate the copied string results in a one-byte overrun SY32 Secure Computing, Lecture 13
Exploiting Off-by-One Errors • Preconditions • Buffer next to saved EBP • 32-bit alignment • Little-endian architecture • Event • Attempt to null-terminate buffer contents, resulting in one-byte overrun • Consequences • LSB of saved EBP now zero • Saved EBP now points lower in memory—possibly into buffer itself Caller’sstack frame Parameters Saved EIP Saved EBP 0 EBP Buffer ESP SY32 Secure Computing, Lecture 13
Exploiting Off-by-One Errors • Just before function exit, saved EBP is popped off stack into EBP register • On function exit, saved EIP is restored to EIP register and control returns to caller • Just before caller exits, stack pointer is moved to address in EBP register, with aim of restoring the saved EIP… • …instead, attacker-supplied address is loaded into EIP register, and we have control! SY32 Secure Computing, Lecture 13
Third-Generation Flaws • Format string vulnerabilities • First appeared in Summer 2000 • Affect the *printf family of functions • Allow reading from & writing to arbitrary addresses • Easy to exploit, but also easy to find and fix • Heap overruns • Less standardized than format string bugs • Allow writing of arbitrary data to arbitrary addresses • Hard to exploit, but also hard to detect SY32 Secure Computing, Lecture 13
Format String Bugs • Two ways of printing a string in C: • printf("%s", input) • printf(input) • Lazy programmers may do the latter, but what if input contains format specifiers? • %n specifier will write data onto the stack • Value could be address of some shellcode… • …which could overwrite saved EIP in stack frame SY32 Secure Computing, Lecture 13
Mitigation • Coding practices • Choice of language • Use of library functions • Memory protection • Recompilation of applications required • No recompilation required SY32 Secure Computing, Lecture 13
Coding Practices • If possible, use languages with intrinsic run-time bounds checking instead of C or C++ • Java, C#, Python, Perl, etc • When writing C++, use its features rather than those of C standard library • std::string class, not char* and strcpy, etc • Use C library functions very carefully • Never, ever, use gets! • Prefer ‘safe’ versions of other functions SY32 Secure Computing, Lecture 13
C Library Risks • High-risk functions include • strcat, strcpy • Use strncat, strncpy – carefully! • printf, sprintf, vsprintf • Always use a format string; use snprintf, not sprintf • scanf, sscanf, vscanf, vsscanf • getopt, getpass, realpath, syslog • Truncate string arguments before passing them in • Some risk with other functions • See WSC2 or BSS for more information • Always check destination buffer is as big as you are claiming, and watch out for off-by-one errors! SY32 Secure Computing, Lecture 13
Safety Through Recompilation • Compile against safer version of C library • Use compiler support for array bounds checking • Patches for GCC: • http://web.inter.nl.net/hcc/Haj.Ten.Brugge/ • /RTCs compiler option in Visual C++ .NET • Protect return address on stack with a canary • StackGuard, http://www.immunix.org/stackguard.html • /GS compiler option in Visual C++ .NET SY32 Secure Computing, Lecture 13
Transparent Protection • Non-executable stack • Example: http://www.openwall.com/linux/ • Requires kernel patch • Won’t trap overruns in heap, data or BSS segments • libverify • Binary rewriting of process memory to force stack verification prior to use • libsafe, http://www.research.avayalabs.com/project/libsafe/ • Estimates safe upper limit on buffer size at run time • Intercepts dangerous library calls, substituting versions that respect buffer size limit SY32 Secure Computing, Lecture 13
Summary • Buffer overruns and related flaws are the major cause of security problems in software • Attacks are varied, but typically involve transfer of control to shellcode supplied by attacker • Partial solutions exist • Compilation of run-time checks into code • Transparent memory protection • Best solution is to avoid C/C++ if possible, or avoid dangerous C library function calls SY32 Secure Computing, Lecture 13