lecture 05 control flow iii

Lecture 05 Control Flow III Stephen Checkoway CS 343 Fall 2020 - PowerPoint PPT Presentation

Lecture 05 Control Flow III Stephen Checkoway CS 343 Fall 2020 Based on Michael Baileys ECE 422 example.c void foo(int a, int b) { char buf1[16]; } int main() { foo(3,6); } example.s (x86) main: pushl %ebp movl %esp, %ebp


  1. Lecture 05 – Control Flow III Stephen Checkoway CS 343 – Fall 2020 Based on Michael Bailey’s ECE 422

  2. example.c void foo(int a, int b) { char buf1[16]; } int main() { foo(3,6); }

  3. example.s (x86) main: pushl %ebp movl %esp, %ebp subl $8, %esp movl $6, 4(%esp) movl $3, (%esp) call foo leave prev FP ret

  4. example.s (x86) main: pushl %ebp movl %esp, %ebp subl $8, %esp movl $6, 4(%esp) movl $3, (%esp) call foo leave prev FP ret

  5. example.s (x86) main: pushl %ebp movl %esp, %ebp subl $8, %esp movl $6, 4(%esp) movl $3, (%esp) call foo leave prev FP ret

  6. example.s (x86) main: pushl %ebp movl %esp, %ebp subl $8, %esp movl $6, 4(%esp) movl $3, (%esp) call foo 6 leave prev FP ret

  7. example.s (x86) main: pushl %ebp movl %esp, %ebp subl $8, %esp movl $6, 4(%esp) movl $3, (%esp) 3 call foo 6 leave prev FP ret

  8. example.s (x86) main: pushl %ebp movl %esp, %ebp subl $8, %esp return movl $6, 4(%esp) movl $3, (%esp) 3 call foo 6 leave prev FP ret

  9. example.s (x86) foo: pushl %ebp movl %esp, %ebp main FP subl $16, %esp return leave ret 3 6 prev FP

  10. example.s (x86) foo: pushl %ebp movl %esp, %ebp main FP subl $16, %esp return leave ret 3 6 prev FP

  11. example.s (x86) foo: … pushl %ebp movl %esp, %ebp main FP subl $16, %esp return leave ret 3 6 prev FP

  12. example.s (x86) foo: … pushl %ebp movl %esp, %ebp main FP subl $16, %esp return leave ret 3 6 mov %ebp, %esp prev FP pop %ebp

  13. example.s (x86) foo: … pushl %ebp movl %esp, %ebp main FP subl $16, %esp return leave ret 3 6 mov %ebp, %esp prev FP pop %ebp

  14. example.s (x86) foo: … pushl %ebp movl %esp, %ebp subl $16, %esp return leave ret 3 6 mov %ebp, %esp prev FP pop %ebp

  15. example.s (x86) foo: … pushl %ebp movl %esp, %ebp subl $16, %esp return leave ret 3 6 mov %ebp, %esp prev FP pop %ebp

  16. example.s (x86) main: … pushl %ebp movl %esp, %ebp subl $8, %esp movl $6, 4(%esp) movl $3, (%esp) 3 call foo 6 leave prev FP mov %ebp, %esp ret pop %ebp

  17. example.s (x86) main: … pushl %ebp movl %esp, %ebp subl $8, %esp movl $6, 4(%esp) movl $3, (%esp) call foo leave prev FP mov %ebp, %esp ret pop %ebp

  18. example.s (x86) main: … pushl %ebp movl %esp, %ebp subl $8, %esp movl $6, 4(%esp) movl $3, (%esp) call foo leave mov %ebp, %esp ret pop %ebp

  19. How does the function know where to return when it executes the ret instruction? A. It returns to the value in eax B. It returns to the value in eip C. It pops the return address off the top of the stack and returns there D. It uses eax as a pointer and loads the return address from the memory location pointed to by eax E. It uses eip as a pointer and loads the return address from the memory location pointed to by eip

  20. What happens if the return address on the stack becomes corrupted and points to the wrong place? A. The program crashes B. The program raises an exception C. The program returns to the correct place regardless of the stack D. The program returns to the wrong location E. It depends on the corrupted value

  21. Buffer overflow example void foo(char *str) { char buffer[16]; strcpy(buffer, str); } int main() { char buf[256]; memset(buf, ‘A’, 255); buf[255] = ‘\x00’; foo(buf); }

  22. Buffer overflow example void foo(char *str) { char buffer[16]; strcpy(buffer, str); } int main() { char buf[256]; memset(buf, ‘A’, 255); buf[255] = ‘\x00’; foo(buf); }

  23. Buffer overflow example void foo(char *str) { char buffer[16]; strcpy(buffer, str); } int main() { char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; foo(buf); prev FP }

  24. Buffer overflow example void foo(char *str) { char buffer[16]; strcpy(buffer, str); } int main() { foo_arg1 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; foo(buf); prev FP }

  25. Buffer overflow example void foo(char *str) { char buffer[16]; strcpy(buffer, str); } return int main() { foo_arg1 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; foo(buf); prev FP }

  26. Buffer overflow example void foo(char *str) { char buffer[16]; strcpy(buffer, str); main FP } return int main() { foo_arg1 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; foo(buf); prev FP }

  27. Buffer overflow example void foo(char *str) { char buffer[16]; strcpy(buffer, str); main FP } return int main() { foo_arg1 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; foo(buf); prev FP }

  28. Buffer overflow example void foo(char *str) { AAAAAAA… char buffer[16]; strcpy(buffer, str); 0x41414141 } 0x41414141 int main() { 0x41414141 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; foo(buf); prev FP }

  29. Buffer overflow example void foo(char *str) { AAAAAAA… char buffer[16]; strcpy(buffer, str); 0x41414141 mov %ebp, %esp } pop %ebp 0x41414141 ret int main() { 0x41414141 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; foo(buf); prev FP }

  30. Buffer overflow example void foo(char *str) { AAAAAA… char buffer[16]; strcpy(buffer, str); 0x41414141 mov %ebp, %esp } pop %ebp 0x41414141 ret int main() { 0x41414141 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; foo(buf); prev FP }

  31. Buffer overflow example void foo(char *str) { AAAAAA… char buffer[16]; strcpy(buffer, str); 0x41414141 mov %ebp, %esp } pop %ebp 0x41414141 ret int main() { 0x41414141 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; ? foo(buf); prev FP }

  32. Buffer overflow example void foo(char *str) { AAAAAA… char buffer[16]; strcpy(buffer, str); 0x41414141 mov %ebp, %esp } pop %ebp 0x41414141 ret int main() { 0x41414141 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; ? foo(buf); prev FP }

  33. Buffer overflow example eip = 0x41414141 AAAAAA… 0x41414141 ??? 0x41414141 0x41414141 AAAAAAA… ? prev FP

  34. Buffer overflow FTW • Success! Program crashed! • Can we do better? • Yes • How?

  35. Exploiting buffer overflows void foo(char *str) { char buffer[16]; strcpy(buffer, str); } int main() { char buf[256]; memset(buf, ‘A’, 255); buf[255] = ‘\x00’; ((long*)buf)[5] = (long)buf; foo(buf); }

  36. Exploiting buffer overflows void foo(char *str) { AAAAAAA… char buffer[16]; strcpy(buffer, str); 0x41414141 } buf int main() { 0x41414141 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; ((int*)buf)[5] = (int)buf; prev FP foo(buf); }

  37. Exploiting buffer overflows void foo(char *str) { AAAAAAA… char buffer[16]; strcpy(buffer, str); 0x41414141 mov %ebp, %esp } pop %ebp buf ret int main() { 0x41414141 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; ((int*)buf)[5] = (int)buf; prev FP foo(buf); }

  38. Exploiting buffer overflows void foo(char *str) { AAAAAAA… char buffer[16]; strcpy(buffer, str); 0x41414141 mov %ebp, %esp } pop %ebp buf ret int main() { 0x41414141 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; ((int*)buf)[5] = (int)buf; prev FP foo(buf); }

  39. Exploiting buffer overflows void foo(char *str) { AAAAAAA… char buffer[16]; strcpy(buffer, str); 0x41414141 mov %ebp, %esp } pop %ebp buf ret int main() { 0x41414141 char buf[256]; memset(buf, ‘A’, 255); AAAAAAA… buf[255] = ‘\x00’; ((int*)buf)[5] = (int)buf; prev FP foo(buf); }

  40. What’s the Use? • If you control the source? • If you run the program? • If you control the inputs?

  41. … More realistic vulnerability argv argc 1 #include <stdio.h> return address 2 saved ebp 3 int main(int argc, char *argv[]) { name 4 char name[32]; 5 printf("Enter your name: "); 6 gets(name); 7 printf("Hello %s!\n", name); 8 return 0; 9 } steve $ ./vuln Enter your name: Steve Hello Steve! steve $ perl -e 'print "A" x 40' | ./vuln &name esp → Enter your name: Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA! Segmentation fault (core dumped)

  42. Shellcode • So you found a vuln (gratz)… • How to exploit?

  43. 1 .LC0: Getting a shell 2 .string "/ bin / sh " 3 get_shell : 4 subl $44, % esp 5 movl $.LC0, 24(% esp ) 1 #include <unistd.h> 6 movl $0, 28(% esp ) 2 3 void get_shell() { 7 movl $0, 20(% esp ) 8 leal 20(% esp ), % eax 4 char *argv[2]; 9 movl % eax , 8(% esp ) 5 char *envp[1]; 10 leal 24(% esp ), % eax 6 argv[0] = "/bin/sh"; 11 movl % eax , 4(% esp ) 7 argv[1] = NULL; 8 envp[0] = NULL; 12 movl $.LC0, (% esp ) 13 call execve 9 execve(argv[0], argv, envp); 14 addl $44, % esp 10 } 15 ret 11 16 main : 12 int main() { 13 get_shell(); 17 pushl % ebp 18 movl % esp , % ebp 14 } 19 andl $-16, % esp 20 call get_shell steve $ ./get_shell 21 leave $ 22 ret

Recommend


More recommend