Memory Corruption
The (almost) Complete History...
haroon meer - 2010 @haroonmeer | haroon@thinkst.com
Memory Corruption The (almost) Complete History... haroon meer - - - PowerPoint PPT Presentation
Memory Corruption The (almost) Complete History... haroon meer - 2010 @haroonmeer | haroon@thinkst.com Who ? haroon meer thinkst ? some papers, some books, some talks academic wannabe Why? Why? Why? Why? Why? twitter made me do it!
The (almost) Complete History...
haroon meer - 2010 @haroonmeer | haroon@thinkst.com
haroon meer thinkst ? some papers, some books, some talks academic wannabe
de-mystify some of the otherwise mystical convince you that Solar Designer was skynet
!" #" $!" $#" %!" %#" &!" &#" '!" $(((" %!!!" %!!$" %!!%" %!!&" %!!'" %!!#" %!!)" %!!*" %!!+" %!!(" !" #" $!" $#" %!" %#" &!" $'''" %!!!" %!!$" %!!%" %!!&" %!!(" %!!#" %!!)" %!!*" %!!+" %!!'"
!" #" $!" $#" %!" %#" &!" &#" '!" $(((" %!!!" %!!$" %!!%" %!!&" %!!'" %!!#" %!!)" %!!*" %!!+" %!!(" !" #" $!" $#" %!" %#" &!" $'''" %!!!" %!!$" %!!%" %!!&" %!!(" %!!#" %!!)" %!!*" %!!+" %!!'"
VS.
(read it)
You wont be able to suddenly use free() to obtain a 4-byte write anything anywhere primitive. You will understand what that means. You will be able to see: When that was first used; What prevents it’s use/abuse today;
0x00000000
User
PageTable
4 gig
Kernel
0x00000000
User
PageTable
4 gig
Kernel
0x00000000 User Kernel
3 gig
0x00000000 User Kernel 0x00000000 User Kernel
0x00000000 User Kernel
3 gig
0x00000000 User Kernel 0x00000000 User Kernel
Kernel
0x00000000 User
PageTable
4 gig
Kernel
0x00000000 User
4 gig
Kernel
0x00000000 User
4 gig
Kernel
0x00000000
0x00000000 User
4 gig
Kernel
0x00000000 Text
0x00000000 User
4 gig
Kernel
0x00000000 Text Data
0x00000000 User
4 gig
Kernel
0x00000000 Text Data ...
0x00000000 User
4 gig
Kernel
0x00000000 Text Data ... Heap Grows Upwards
0x00000000 User
4 gig
Kernel
0x00000000 Text Data ... Heap Grows Upwards mmap (Shared Memory)
0x00000000 User
4 gig
Kernel
0x00000000 Text Data ... Heap Grows Upwards mmap (Shared Memory) Stack Grows Downwards
0x00000000 User
4 gig
Kernel
0x00000000 Text Data ... Heap Grows Upwards mmap (Shared Memory) Stack Grows Downwards
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Upwards Grows Downwards 0x00000000 Stack mmap (Shared Memory) Heap Text Data ...
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Upwards Grows Downwards 0x00000000 Stack mmap (Shared Memory) Heap Text Data ...
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 Saved EIP Saved EBP int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 Saved EIP Saved EBP int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 int i Saved EIP Saved EBP int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 int i Saved EIP Saved EBP int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 int i Saved EIP function_1 argument_2 (b) function_1 argument_1 (a) Saved EBP int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 int i Saved EIP function_1 argument_2 (b) function_1 argument_1 (a) Saved EBP int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 int i Saved EIP function_1 argument_2 (b) function_1 argument_1 (a) Saved EBP Saved EIP Saved EBP int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 int i Saved EIP function_1 argument_2 (b) function_1 argument_1 (a) Saved EBP Saved EIP Saved EBP int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 int i Saved EIP function_1 argument_2 (b) function_1 argument_1 (a) Saved EBP int j Saved EIP Saved EBP int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 int i Saved EIP function_1 argument_2 (b) function_1 argument_1 (a) Saved EBP Saved EIP Saved EBP int argc char **envp char **argv
int function_1(int a, int b) { int j; // do stuff return j; } int main(int argc, char **argv, char **envp) { int i; i = function_1(1,2); printf(“answer is %d”, i) return i; }
Grows Downwards 0x00000000 int i Saved EIP function_1 argument_2 (b) function_1 argument_1 (a) Saved EBP int argc char **envp char **argv
Stack Grows Downwards Saved EIP function_1 argument_1 (a) Saved EBP int j Saved EIP Saved EBP int argc char **envp char **argv buff
Overflow Direction
Where to go
strcpy(buf1, buf2);
strcpy(buf1, buf2);
strcpy(buf1, buf2); char buf1[4]; strncpy(buf1, buf2, 4);
strcpy(buf1, buf2); char buf1[4]; strncpy(buf1, buf2, 4);
strcpy(buf1, buf2); char buf1[4]; strncpy(buf1, buf2, 4);
T E S T I N G \0
char buf1[4] char buf2[] = “TESTING”
strcpy(buf1, buf2); char buf1[4]; strncpy(buf1, buf2, 4);
T E S T I N G \0
char buf1[4] char buf2[] = “TESTING”
T E S T
strcpy(buf1, buf2); char buf1[4]; strncpy(buf1, buf2, 4);
T E S T I N G \0
char buf1[4] char buf2[] = “TESTING”
T E S T
printf(“buf1 is [%s]\n”,buf1);
strcpy(buf1, buf2); char buf1[4]; strncpy(buf1, buf2, 4);
T E S T I N G \0
char buf1[4] char buf2[] = “TESTING”
T E S T
printf(“buf1 is [%s]\n”,buf1); $ buf1 is [TESTTESTING]
bk fd bk fd bk fd 7 8 9
bk fd bk fd bk fd 7 8 9 [x] [8] [7] [9] [8] [x] 7 8 9 back forward back forward
[x] [8] [7] [9] [8] [x] 7 8 9 back forward back forward
[x] [8] [7] [9] [8] [x] 7 8 9 back forward back forward [x] [8] [7] [9] [8] [x] 7 8 9 back forward back forward
[x] [9] [7] [9] [8] [x] 7 8 9 back forward back
[x] [9] [7] [9] [7] [x] 7 8 9 forward back
[x] [9] [7] [9] [7] [x] 7 8 9 forward back WHERE WHAT
* Peter Szor - analysis of the slapper worm
Stack Growth Saved EBP int j Saved EIP buff
Overflow Direction
Pointers Arguments
int func(char *a, char *b) { char buf[12]; strcpy(buf, a); strcpy(b, buf); return 1; }
Stack Growth Saved EBP int j Saved EIP buff
Overflow Direction
Pointers Arguments
int func(char *a, char *b) { char buf[12]; strcpy(buf, a); strcpy(b, buf); return 1; }
Stack Growth Saved EBP int j Saved EIP buff
Overflow Direction
Pointers Arguments (shadow copy) Arguments
Everything executable --> DEP DEP vs ret-2-libc (ROP)
ASLR to beat ret-2-libc / ROP Single leaked / static address beats ASLR Partial Overwrites App specific..
ASLR to beat ret-2-libc / ROP Single leaked / static address beats ASLR Partial Overwrites App specific..
Stack Growth int x int j function pointer b buff LSB's MSB's function pointer a
Overflow Direction
DEP without ASLR ASLR without DEP without
What the ASLR/DEP taketh.. The rich client side applications giveth back.
much research http://ilm.thinkst.com/folklore/
@haroonmeer haroon@thinkst.com http://blog.thinkst.com