330 likes | 343 Views
This article explores the memory organization, program execution, stack, and function call in writing secure code. It discusses common software flaws and provides solutions to prevent them, such as validating input and improving error handling. Additionally, it covers buffer overflow vulnerabilities and methods to mitigate them.
E N D
Writing Secure Code:Software Flaws Based on: “19 Deadly Sins of Software Security – Programming Flaws and How to Fix Them”, Michael Howard, David LeBlanc and John Viega
Outline (1/3) • Memory Organization • Program Execution • Stack • Function Call
Outline (2/3) • Overflows • Stack Overrun • Heap Overrun
Outline(3/3) • Solutions • Validate input • Improper Error Handling • Summary • Buffer Overflow • Conclusion
Program Execution • Text Segment -> Program Code • Data Segment -> Static variables • Stack -> Functions, Dynamic variables • Heap -> Dynamic Memory Allocation
Stack Evolution Execute ‘printf’ Return of ‘printf’ void foo(char *str){ printf(str); } int main(){ printf(“\nMessage-1”); foo(“\nMessage-2”); } Start execution from ‘main’ Stack frame of printf() Execute ‘printf’ Return of ‘’printf Stack frame of printf() Stack frame of foo() Execute ‘foo’ Return of ‘foo’ Stack frame of main() Return of ‘main’
Stack • Last In First Out (LIFO) • Push (modify SP) • Pop (modify SP) • Top - Stack Pointer (SP) • Stack Frames • Frame Pointers (FP) (optional) • Local Base Pointer (LB) • Extended Base Pointer (EBP) – Reference to local variables (optional) • Stack Bottom – At fixed address
Stack Frame Parameters Return Address Calling Frame Pointer Local Variables SP+offset SP Addresses 00000000
Function Call • Prologue • Save state of the stack • Reserve required memory for the new function • Function Call • Push function’s parameters on the stack • Save Instruction Pointer (IP) • Function Return • Restore the organization of memory to the state immediately prior to calling the function
Function Call Sample Bottom of stack Top of memory 18 return address {addressof(y=3)} saved stack pointer y x buf Top of stack Bottom of memory x=2; foo(18); y=3; void foo(int j){ int x,y; char buf[100]; … }
Buffer Overflow • It is used since ’80 • 1988: Morris Worm • Buffer Overflowinsendmail • Become known at 1996 • Aleph One – Smashing the stack for fun and profit (Phrack)
Languages effected • C/C++ • Libraries written in C/C++ or Assembly • Older languages
Stack buffer overflow (1/6) • A buffer overflow is the result of stuffing more data into a buffer than it can handle • If the buffer is locating at the stack -> Stack Overflow • If the buffer is locating at the heap -> Heap Overflow
Stack buffer overflow (2/6) *s return address saved stack pointer buf void function (char *s){ char buf[8]; strcpy(buf,s); } void main(){ char large_string[256]; int i; for (i=0;i<255;i++) large_string[i]=‘A’; function(large_string); } • The function copies a supplied string without bounds checking by using strcpy() • If you run this program you will get a segmentation violation
Stack buffer overflow (3/6) …. • The first 8 chars from s are copied at the memory space allocated from buf • The rest 248 chars from s, overwrite the next 248 bytes in the stack • As a result the return address takes the value 0x41414141 (0x41 -> the hex representation of ‘A’), which is invalid for the program • Then the IP takes the value 0x41414141 • When the program tries to execute the next code instruction from IP, there occur a Segmentation Fault
Stack buffer overflow (4/6) • Buffer overrun attacks exploit a lack of bounds-checking on the size of input being stored in a buffer array • By writing data past the end of an allocated array, the malicious user can make arbitrary changes to the program state stored adjacent to the array
Stack buffer overflow (5/6) • Main Idea: Instead of an invalid address, use a valid address in the memory space of the process as the new return address of the function: • Return to another code instruction of the program • Or put shellcode in the overflowed buffer and return at the beginning of that code
Stack buffer overflow (6/6) • Execution of the main program • After the function call of process A • Put shellcode in local buffer B, overflow and overwrite the return address in order to return at the beginning of the shellcode
Redemption Steps • Replace dangerous String Handling Functions • strcpy -> strncpy, strlcpy (*nix), strcpy_s (CRT windows) • Audit Allocations • Check Loops and Array Accesses • Use Analysis Tools • Stack Protection • StackGuard (canary: terminator, random, or random XOR), Randomization, Stack Cookies • Use non-executable Stack and Heap • Solaris: non-executable stack patch
Examples (1/2) • Code Red Worm • http://en.wikipedia.org/wiki/Code_Red_worm • Pine • A remotely exploitable buffer overflow exists within the parsing of the message/external-body type attribute name/value pairs • http://www.derkeiler.com/Mailing-Lists/Securiteam/2003-09/0025.html • Winamp • The remote version of this software is vulnerable to a local buffer overrun when handling a large file name • http://shalb.com/kb/entry/16199/
Examples (2/2) • CVE-1999-0042 : “IMAP • CVE-2000-0389 : “Kerberos 4 and 5” • CVE-2000-0390 : “Kerberos 5” • CVE-2000-0391 : “Kerberos 5” • CVE-2000-0392 : “Kerberos 5” • CVE-2002-0842 : “Oracle9i Application Server 9.02” • CVE-2003-0095 : “Oracle Database Server 9i, 8i, 8.1.7, 8.0.6” • CVE-2003-0096 : “Oracle 9i Database Release 2, Release 1, 8i, 8.1.7, 8.0.6” • CAN-2003-0352 : “DCOM interface for RPC in Microsoft Windows NT 4.0, 2000, XP, Server 2003” • CA-2003-05 : “Multiple Vulnerabilities in Oracle Servers” • CA-2003-23 : “RPCSS Vulnerabilities in Microsoft Windows”
References • Smashing The Stack For Fun And Profit, by Aleph1 (Elias Levy) • www.insecure.org/stf/smashstack.txt • Writing secure Code, Second Edition, by Michael Howard and David C. LeBlanc • Defeating the Stack Based Buffer Overflow Prevention Mechanism of Microsoft windows Server 2003, by David Litchfield • www.ngssoftware.com/papers/defeating-w2k3-stack-protecion.pdf • The Tao of Windows Buffer Overflows, by Dildog • www.cultdeadcow.com/cDc_files/cDc-351/
Heap Buffer Overflow • Overflow a buffer that is located at heap • Similar to stack buffer overflow • But more difficult to exploit • Typically, it is used in order to change the access rights of the program
Heap buffer overflow attack • Variables such as • passwords • file names • uid • gid are putted on the heap • A malicious user, use heap overflow attacks to overwrite these variables and gain unauthorized access rights
Other problems • Many programmers don’t think that heap overrun attacks are executable • Stack protection mechanisms, like StackGuard, don’t protect heap • In some operating systems, there is a choice to make the stack non-executable, but there is no such a choice for the heap • By a successful heap overflow attack, the Stack protection mechanisms can be bypassed
History • The first heap overrun problem was detected at BSDI crontab in 1996 • A heap buffer was overflowed by coping a large file name • The exploit turn the variables uid and gid to zero and the attacker gain unauthorized access rights
Interesting Example (1/2) • Mnogosearch search engine written in C • Vulnerability in the URL decoding caused a heap overflow. • There was a number of variables in BSS space. One of which was used to send returned data to the client. Another of which was a pointer to memory used to hold variables passed in the url. Something like: void **variables = malloc(sizeof(void *) * variableindex); char Targ[8192];
Interesting Example (2/2) • Variables were inserted into ‘variables’ like so: variables[variable_index++] = strdup(data); • Using these two behaviours we could overwrite various addresses until we found the address of Targ (we know when we receive corrupted data back over the network) • Once we know the address of Targ we then know the address, relatively, of ‘variables’ • If we overwrite ‘variables’ with a rough guess of the GOT we then overwrite multiple GOT entries with addresses returned by strdup of our shellcode – 100% accurate!
Examples • Heap Overrun in HTR Chunked Encoding Could Enable Web Server Compromise • www.microsoft.com/technet/security/Bulletin/MS02-028.mspx
Solutions: Validate Input • Never trust any input • You must ALWAYS VALIDATE INPUT • Always prefer POSITIVE vetting • Positive vs. Negative vetting • If you only test for things you want to keep out, you will always miss something (Negative) • Always test to see if you got what you expected and kick out anything you didn’t (Positive) • It is always easier to ease restrictions than to cleanup bad data after the fact
Solutions: Improper Error Handling • Don’t give an attacker more info • Definitely give the user an indication that there was an error • and IF there is something that they can do about it, by all means let them know how to proceed • If there is nothing they can reasonably do about the problem • Give them some way to uniquely (and abstractly) identify the error and point them to support • Then, LOG all the info so the support folks can get at it by that identifier • Never give the user any information that they didn’t already have • NEVER directly display info from an exception • NEVER tell a user WHY an authentication or authorization failure occurred • NEVER give the user back any info that they entered directly
Buffer Overflow Summary • Do carefully check you buffer accesses by using safe string and buffer handling functions • Do use OS-level based defenses • Do understand what data the attacker controls and manage that data safely in your code • Do not think that compiler and OS defenses are sufficient • Do not create new code that uses unsafe functions
Conclusion • Writing code is easy • Writing safe code takes a lot of work • Your best programmers should be performing the code reviews • Schedule an application review and ethical hack of new applications before they go into production