More Bufger Overfmows 1
midterm 1 kernel density plot; red lines: 25/50/75th perecentile; green line: mean 2 50 60 70 80 90 100
last time stack smashing particular exploit technique for bufger overfmows bufger overfmow = out-of-bounds access to array condition: bufger on the stack two steps: insert machine code overwrite return address to point there 3
stack smashing: the tricky parts construct machine code that works in any executable same tricks as writing relocatable virus code usual idea: just execute shell (command prompt) construct machine code that’s valid input machine code usually fmexible enough fjnding location of return address fjxed ofgset from bufger fjnding location of inserted machine code 4
stack smashing: the tricky parts construct machine code that works in any executable same tricks as writing relocatable virus code usual idea: just execute shell (command prompt) construct machine code that’s valid input machine code usually fmexible enough fjnding location of return address fjxed ofgset from bufger fjnding location of inserted machine code 5
machine code that works anywhere need relocatable machine code relative addressing internally absolute addressing of program 6
stack smashing: the tricky parts construct machine code that works in any executable same tricks as writing relocatable virus code usual idea: just execute shell (command prompt) construct machine code that’s valid input machine code usually fmexible enough fjnding location of return address fjxed ofgset from bufger fjnding location of inserted machine code 7
valid input? common restrictions: no 0 bytes, no newlines machine code is fmexible enough, but tricky example: mov $0x100, %rax has 0 s in encoding of 0x100 xor %eax, %eax mov $0x100, %al 8
stack smashing: the tricky parts construct machine code that works in any executable same tricks as writing relocatable virus code usual idea: just execute shell (command prompt) construct machine code that’s valid input machine code usually fmexible enough fjnding location of return address fjxed ofgset from bufger fjnding location of inserted machine code 9
location of return address easiest part, but … depends on what compiler does variable number of saved registers … read assembly? 10
stack smashing: the tricky parts construct machine code that works in any executable same tricks as writing relocatable virus code usual idea: just execute shell (command prompt) construct machine code that’s valid input machine code usually fmexible enough fjnding location of return address fjxed ofgset from bufger fjnding location of inserted machine code 11
stack location? $ cat stackloc.c #include <stdio.h> int main(void) { int x; printf("%p\n", &x); } $ ./stackloc.exe 0x7ffe8859d964 $ ./stackloc.exe 0x7ffd4e26ac04 $ ./stackloc.exe 0x7ffc190af0c4 12
address space layout randomization vary the location of things in memory including the stack designed to make exploiting memory errors harder will talk more about later 13
disabling ASLR Switching on ADDR_COMPAT_LAYOUT. 0x7fffffffe064 $ ./stackloc.exe 0x7fffffffe064 $ ./stackloc.exe 0x7fffffffe064 $ ./stackloc.exe Switching on ADDR_NO_RANDOMIZE. $ cat stackloc.c $ setarch x86_64 -vRL bash } printf("%p\n", &x); int x; int main(void) { #include <stdio.h> 14
fjnding stack location run program in a debugger (e.g., GDB) set breakpoint at relevant location b functionName b *0x12345678 (by address) output %rsp p $rsp info registers 15
stack location? (take 2) Breakpoint 1, 0x00000000004005b6 in main () (gdb) [Inferior 1 (process 15441) exited normally] 0x7fffffffdfe4 (gdb) continue $1 = (void *) 0x7fffffffdff8 (gdb) p $rsp Starting program: /home/cr4bd/spring2017/cs4630/slides/20170307/stackloc.exe $ ./stackloc.exe (gdb) run Breakpoint 1 at 0x4005b6 (gdb) break main ... $ gdb ./stackloc.exe 0x7fffffffe064 16
Linux, initial stack pointer to bar array of pointers to args (argv) array of pointers to env. vars. command-line arguments environment variables ./test.exe foo bar actual initial stack pointer pointer to ./test.exe pointer to foo NULL pointer (end of list) top of stack at pointer to PATH env. var. pointer to HOME env. var. NULL pointer (end of list) "./test.exe" "foo" "bar" "PATH=/usr/bin:/bin" "HOME=/home/cr4bd" 0x7ffffffff000 17
on using GDB cheat sheet on website 18
gdb demo 19
trigger segfault mov $1 = (void *) 0x7fffffffdff8 (gdb) p $rsp End of assembler dump. retq => 0x000000000040053b <+21>: $0x18,%rsp add 0x0000000000400537 <+17>: 0x400410 <gets@plt> callq 0x0000000000400532 <+12>: $0x0,%eax 0x000000000040052d <+7>: gdb ./a.out %rsp,%rdi mov 0x000000000040052a <+4>: $0x18,%rsp sub 0x0000000000400526 <+0>: Dump of assembler code for function vulnerable: (gdb) disass 0x000000000040053b in vulnerable () Program received signal SIGSEGV, Segmentation fault. Starting program: /path/to/a.out (gdb) run <big-input.txt ... 20
trigger segfault — stripped gdb ./a.out ... (gdb) run <big-input.txt Starting program: /path/to/a.out Program received signal SIGSEGV, Segmentation fault. 0x000000000040053b in ?? () (gdb) disassemble No function contains program counter for selected frame. (gdb) x/i $rip => 0x40053b: retq (gdb) 21
stripping you can remove debugging information from executables Linux command: strip GCC option -s disassemble can’t tell where function starts 22
disassembly attempts sbb (gdb) End of assembler dump. retq => 0x000000000040053b: $0x18,%rsp add 0x0000000000400537: Dump of assembler code from 0x400537 to 0x40053c: (gdb) disassemble $rip-4,$rip+1 End of assembler dump. %al,%bl 0x000000000040053a: gdb ./a.out (bad) 0x0000000000400539: -0x7d(%rax) decl 0x0000000000400536: Dump of assembler code from 0x400536 to 0x40053c: (gdb) disassemble $rip-5,$rip+1 0x000000000040053b in ?? () Program received signal SIGSEGV, Segmentation fault. Starting program: /path/to/a.out (gdb) run <big-input.txt ... 23
other notable debugger commands b *0x12345 — set breakpoint at address can set breakpoint on machine code on stack watchpoints — like breakpoints but trigger on change to/read from value “when is return address overwritten” 24
debugging demo 25
stopping stack smashing? how can you stop stack smashing? stop overrun — bounds-checking stop return to attacker code stop execution of attacker code 26
stopping stack smashing? how can you stop stack smashing? stop overrun — bounds-checking stop return to attacker code stop execution of attacker code 26
exploit mitigations idea: turn vulnerablity to something less bad e.g. crash instead of machine code execution many of these targetted at bufger overfmows 27
mitigation agenda we will look briefmy at one mitigation — stack canaries then look at exploits that don’t care about it then look at more fmexible mitigations then look at more fmexible exploits 28
mitigation priorities efgective? does it actually stop the attacker? fast? how much does it hurt performance? generic? does it require a recompile? rewriting software? recurring theme: stop stack smashing, but not other bufger overfmows 29
stopping stack smashing? how can you stop stack smashing? stop overrun — bounds-checking stop return to attacker code stop execution of attacker code 30
recall: RE xor %fs:0x28, %rdi call __stack_chk_fail call_stack_chk_fail: ret add $0x28, %rsp jne call_stack_chk_fail mov 0x18(%rsp), %rdi /* copy value from stack */ ... ... ... mov %rax, 0x18(%rsp) /* ... on to stack, before return address */ mov %fs:0x28, %rax 31 /* copy value from thread − local storage */ /* xor with value in thread − local storage */ /* if result non − zero, do not return */
recall: RE xor %fs:0x28, %rdi call __stack_chk_fail call_stack_chk_fail: ret add $0x28, %rsp jne call_stack_chk_fail mov 0x18(%rsp), %rdi /* copy value from stack */ ... ... ... mov %rax, 0x18(%rsp) /* ... on to stack, before return address */ 31 /* copy value from thread − local storage */ mov %fs:0x28, %rax /* xor with value in thread − local storage */ /* if result non − zero, do not return */
recall: RE xor %fs:0x28, %rdi call __stack_chk_fail call_stack_chk_fail: ret add $0x28, %rsp jne call_stack_chk_fail 31 /* copy value from stack */ ... ... ... mov %rax, 0x18(%rsp) /* ... on to stack, before return address */ mov %fs:0x28, %rax /* copy value from thread − local storage */ mov 0x18(%rsp), %rdi /* xor with value in thread − local storage */ /* if result non − zero, do not return */
stack canary increasing addresses highest address (stack started here) lowest address (stack grows here) return address for vulnerable : 37 fd 40 00 00 00 00 00 (0x40fd37) canary: b1 ab bd e8 31 15 df 31 unused space (12 bytes) bufger (100 bytes) return address for scanf machine code for the attacker to run 32
Recommend
More recommend