Buffer overflow and stack smashing attacks Principles of

Buffer overflow and stack smashing attacks Principles of application software security

Buffer overflows q. One of the most common vulnerabilities in software q. Particularly problematic when present in system libraries and other code that runs with high execution privileges.

How it works q Application reserves adjacent memory locations (buffer) to store arguments to a function, or variable values. q Attacker gives an argument too long to fit in the buffer. q The application copies the whole argument, overflowing the buffer and overwriting memory space. q If the conditions are “just right” this will enable to attacker to gain control over the program flow and execute arbitrary code, with the same privileges of the original application.

Stack smashing <previous stack frame> function arguments return address previous frame pointer local variables local buffer variables Direction of stack growth q Function (subroutine) calls results in an activation frame being pushed onto a memory area called the stack.

Memory management Stack Direction of stack growth Direction of heap growth Heap unitialized variables initialized variables code instructions q The stack, which contains activation frames, starts at the highest memory address allocated for the process, and grows downwards q Variable-length data (e. g. , strings) that are read dynamically, are kept in the heap, which grows upwards q This arrangement maximizes flexibility of virtual memory management

How to smash <previous stack frame> function arguments Return address (overwritten with entry address of malicious code) Previous frame pointer (overwritten w/ malicious code) local variables (overwritten w/ malicious code) local buffer variables (overwritten w/ malicious code) Direction of stack growth q Give application a very long string with malicious code q The string length, being much larger than the space allocated in the heap (buffer size declaration) causes the heap to overflow into the stack and overwrites the return address q The return address now points to the beginning of the malicious code
![void hello(char *tag) { char inp[16]; printf("Enter value for %s: ", tag); gets(inp); printf("Hello void hello(char *tag) { char inp[16]; printf("Enter value for %s: ", tag); gets(inp); printf("Hello](http://slidetodoc.com/presentation_image_h/780e08164a4775726ba43d5a4d55c60e/image-7.jpg)
void hello(char *tag) { char inp[16]; printf("Enter value for %s: ", tag); gets(inp); printf("Hello your %s is %sn", tag, inp); } (a) Basic stack overflow C code $ cc -g -o buffer 2. c $. /buffer 2 Enter value for name: Bill and Lawrie Hello your name is Bill and Lawrie buffer 2 done $. /buffer 2 Enter value for name: XXXXXXXXXXXXXXXXXX Segmentation fault (core dumped) $ perl -e 'print pack("H*", "414243444546474851525354555657586162636465666768 08 fcffbf 948304080 a 4 e 4 e 0 a"); ' |. /buffer 2 Enter value for name: Hello your Re? pyy]u. EA is ABCDEFGHQRSTUVWXabcdefguyu Enter value for Kyyu: Hello your Kyyu is NNNN Segmentation fault (core dumped) (b) Basic stack overflow example runs Figure 10. 5 Basic Stack Overflow Example

Memory Address. . bffffbe 0 >. . . bffffbdc. . bffffbd 8. . bffffbd 4 `. . . bffffbd 0 0 V. @ bffffbcc. . bffffbc 8. . bffffbc 4 <. . . bffffbc 0 4. . . Before gets(inp). . After gets(inp) Contains Value of . . 3 e 850408. . f 0830408. . e 8 fbffbf. . 60840408 00850408 tag 94830408 return addr e 8 ffffbf old base ptr 65666768 e f g h 30561540 a b c 1 b 840408 U V W e 8 fbffbf Q R S 3 cfcffbf E F G 34 fcffbf A B C. . d X T H D 61626364 55565758 inp[12 -15] 51525354 inp[8 -11] 45464748 inp[4 -7] 41424344 inp[0 -3] . . . . Figure 10. 6 Basic Stack Overflow Stack Values

void getinp(char *inp, int siz) { puts("Input value: "); fgets(inp, siz, stdin); printf("buffer 3 getinp read %sn", inp); } Stack Overflo w Exampl e void display(char *val) { char tmp[16]; sprintf(tmp, "read val: %sn", val); puts(tmp); } int main(int argc, char *argv[]) { char buf[16]; getinp(buf, sizeof(buf)); display(buf); printf("buffer 3 donen"); } (a) Another stack overflow C code $ cc -o buffer 3. c $. /buffer 3 Input value: SAFE buffer 3 getinp read SAFE read val: SAFE buffer 3 done $. /buffer 3 Input value: XXXXXXXXXXXXXXXXXX buffer 3 getinp read XXXXXXXX read val: XXXXXXXX buffer 3 done Segmentation fault (core dumped) (b) Another stack overflow example runs Figure 10. 7 Another Stack Overflow Example

Canary Guards q. Like the legendary canary-in-the-mine, it detects stack smash attacks. q. Inserts a “Canary value” just below the return address (Stack Guard) or just below the previous frame pointer (Stack Smashing Protector). This value gets checked right before a function returns.

SSP <previous stack frame> function arguments return address previous frame pointer Canary value local buffer variables local non-buffer variables Direction of stack growth q Prevents overflow of local buffer variables q Canary value checking only takes place at return time, so other attacks possible

Alternatives to canaries q. Use a compiler that does full bounds checking, i. e. , makes sure that the code always allocate enough memory for arguments v. Significant performance penalty (Java/C)

Static analysis q Use a code analyzer to detect buffer overflows v. Since checking that arbitrary code does not overflow is an undecidable problem, the code must be annotated in order for this to work § Depends on programmer expertise (costly) § Some common and useful programming techniques are prohibited (performance and engineering costs) v. Advantage is that the compiled code does not suffer from performance deterioration

Safe libraries q. Many vulnerabilities in code are due to unsafe use of system libraries q. An alternative is to install a kernel patch that dynamically substitutes calls to unsafe library functions for safe versions of those q. Not possible for closed-source systems such as MS operating systems

Memory address randomization q Patch at the kernel level, changing the memory mapping v. Small performance penalty, by extra memory lookups (actually, extra cache lookups) q Makes it very difficult to perform a useful buffer overflow v. However, unlike some other strategies, does not improve robustness (liveness) properties
- Slides: 15