700 likes | 838 Views
CS419/579 Cyber Attacks & Defense. Frame Pointer (i.e., Base Pointer, ebp ) Attack 10/10/19. Points to somewhere up…. Buffer Overflow. NO ARG…. get_a_shell (). 0x64646464. % ebp. 0x63636363. 0x62626262. 0x61616161. 0x31313131. Buffer at ebp-0x10. ARG1: 41414141. % esp.
E N D
CS419/579Cyber Attacks & Defense Frame Pointer (i.e., Base Pointer, ebp) Attack 10/10/19
Points to somewhere up… Buffer Overflow NO ARG… get_a_shell() 0x64646464 %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp • 4 byte buffer… • What if you type “1111aaaabbbbccccddddeeee”? • Overwrites the return address! • Can you set that as the address of • get_a_shell()?
Points to somewhere up… Buffer Overflow NO ARG… get_a_shell() 0x64646464 %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp Function return of receive_input add $0x54,%esp pop %esi pop %ebp ret
Points to somewhere up… Buffer Overflow NO ARG… get_a_shell() 0x64646464 %ebp 0x63636363 %esp 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 Function return of receive_input add $0x54,%esp pop %esi pop %ebp ret
Points to somewhere up… Buffer Overflow NO ARG… get_a_shell() 0x64646464 %esp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 Function return of receive_input add $0x54,%esp pop %esi pop %ebp ret
Points to somewhere up… Buffer Overflow NO ARG… %ebp: 0x64646464, INVALID get_a_shell() %esp 0x64646464 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 Function return of receive_input add $0x54,%esp pop %esi pop %ebp ret
Points to somewhere up… Buffer Overflow NO ARG… %ebp: 0x64646464, INVALID %esp get_a_shell() 0x64646464 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 Run get_a_shell()! ARG1: 41414141 Function return of receive_input add $0x54,%esp pop %esi pop %ebp ret
Points to somewhere up… Function Epilogue NO ARG… RET_ADDR Saved %ebp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp Function return of receive_input add $0x54,%esp pop %esi pop %ebp ret
Points to somewhere up… Function Epilogue NO ARG… get_a_shell() RET_ADDR 0x64646464 Saved %ebp %ebp 0x63636363 %esp 0x62626262 Move %esp back to the previous point… 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 Function return of receive_input add $0x54,%esp pop %esi pop %ebp ret
Points to somewhere up… Function Epilogue - leave NO ARG… get_a_shell() RET_ADDR 0x64646464 Saved %ebp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp Function return of receive_input leave ret The leave instruction mov %ebp, %esp pop %ebp
Points to somewhere up… Function Epilogue - leave NO ARG… get_a_shell() RET_ADDR 0x64646464 Saved %ebp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp Function return of receive_input leave ret Function return of receive_input leave mov %ebp, %esp pop %ebp ret
Points to somewhere up… Function Epilogue - leave NO ARG… get_a_shell() RET_ADDR 0x64646464 Saved %ebp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp Function return of receive_input leave ret Function return of receive_input leave mov %ebp, %esp pop %ebp ret
Points to somewhere up… Function Epilogue - leave NO ARG… get_a_shell() RET_ADDR 0x64646464 Saved %ebp %esp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 Function return of receive_input leave ret Function return of receive_input leave mov %ebp, %esp pop %ebp ret
Points to somewhere up… Function Epilogue - leave NO ARG… get_a_shell() RET_ADDR 0x64646464 Saved %ebp %esp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 Function return of receive_input leave ret Function return of receive_input leave mov %ebp, %esp pop %ebp ret
Points to somewhere up… %ebp Function Epilogue - leave NO ARG… get_a_shell() RET_ADDR %esp 0x64646464 Saved %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 Function return of receive_input leave ret Function return of receive_input leave mov %ebp, %esp pop %ebp ret
Points to somewhere up… %ebp Function Epilogue - leave NO ARG… %esp get_a_shell() RET_ADDR 0x64646464 Saved %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 Function return of receive_input leave ret Function return of receive_input leave mov %ebp, %esp pop %ebp ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 Saved %ebp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp • The %ebpregister • %esppoints to one end of a function’s stack • %ebppoints to the other end of a function’s stack • A function’s Stack Frame • Starts with %ebp • Ends with %esp
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 Saved %ebp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp • What if an attacker … • Can overwrite saved %ebp • But cannot overwrite return address?
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp • What if an attacker … • Can overwrite saved %ebp • But cannot overwrite return address?
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp • What if an attacker … • Can overwrite saved %ebp • But cannot overwrite return address? • Function epilogue • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 %esp • What if an attacker … • Can overwrite saved %ebp • But cannot overwrite return address? • Function epilogue • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 %esp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 • What if an attacker … • Can overwrite saved %ebp • But cannot overwrite return address? • Function epilogue • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 %esp %ebp 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 • What if an attacker … • Can overwrite saved %ebp • But cannot overwrite return address? • Function epilogue • leave • mov %ebp, %esp • pop %ebp • ret
%ebp 0x64646464 Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR %esp 0x64646464 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 • What if an attacker can… • Overwrite saved %ebp • But cannot overwrite return address? • Function epilogue • leave • mov %ebp, %esp • pop %ebp • ret
%ebp 0x64646464 Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR %esp 0x64646464 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 • What if an attacker can… • Overwrite saved %ebp • But cannot overwrite return address? • Function epilogue • leave • mov %ebp, %esp • pop %ebp • ret
%ebp 0x64646464 Frame Pointer Attack NO ARG… %esp get_a_shell() RET_ADDR 0x64646464 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 • What if an attacker can… • Overwrite saved %ebp • But cannot overwrite return address? • Function epilogue • leave • mov %ebp, %esp • pop %ebp • ret • Return to the correct RET_ADDR • Is it problematic????
%ebp 0x64646464 Frame Pointer Attack NO ARG… %esp get_a_shell() RET_ADDR 0x64646464 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 • Call chain (in bof-level5) • main() -> run() -> receive_input() • We just ran leave-ret in receive_input() • There will be another leave-ret in run() • What will happen if that runs???
%ebp 0x64646464 Frame Pointer Attack NO ARG… %esp get_a_shell() RET_ADDR 0x64646464 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 • Call chain (in bof-level5) • main() -> run() -> receive_input() • leave-ret in run() • leave • mov %ebp, %esp • pop %ebp • ret
%ebp 0x64646464 Frame Pointer Attack NO ARG… %esp get_a_shell() RET_ADDR 0x64646464 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 • Call chain (in bof-level5) • main() -> run() -> receive_input() • leave-ret in run() • leave • mov %ebp, %esp • pop %ebp • ret
%esp %ebp 0x64646464 Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 ARG1: 41414141 • Call chain (in bof-level5) • main() -> run() -> receive_input() • leave-ret in run() • leave • mov %ebp, %esp • pop %ebp • ret
%esp %ebp 0x64646464 Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0x63636363 0x62626262 0x61616161 0x31313131 Buffer at ebp-0x10 Invalid Address 0x64646464!! ARG1: 41414141 %esp = 0x64646464 pop %ebp -> mov(%esp), %ebp add $4, %esp • Call chain (in bof-level5) • main() -> run() -> receive_input() • leave-ret in run() • leave • mov %ebp, %esp • pop %ebp • ret
GDB, break at receive_input’s leave dddd = 0x64646464 Leave mov %ebp, %esp pop %ebp %esp = 0xffffd3e0 %ebp = 0xffffd468
GDB, break at receive_input’s leave dddd = 0x64646464 Leave mov %ebp, %esp pop %ebp %esp = 0xffffd46c %ebp = 0x64646464
GDB, break at run’s leave dddd = 0x64646464 Leave mov %ebp, %esp pop %ebp %esp = 0xffffd470 %ebp = 0x64646464
GDB, break at run’s leave dddd = 0x64646464 Leave mov %ebp, %esp pop %ebp<- fault! %esp = 0x64646464 %ebp = 0x64646464
Exploiting Frame Pointer • We can change the saved %ebp • The %ebpof a function in the upper level • main() -> run() -> receive_input() • (%ebp + 4) stores ‘return address!’ • If that is invalid address such as 0x64646464 • Will generate SIGSEGV, a segmentation fault • What if we put a valid address on it???? • The address that we can control…
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0xffffd530 %ebp 0x63636363 0x62626262 0x61616161 0x31313131 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 %esp Let’s put a stack address at saved %ebp… Suppose our original %ebp = 0xffffd540 ebp-0x10 = 0xffffd530
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0xffffd530 %ebp 0x63636363 0x62626262 0x61616161 0x31313131 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 %esp • Function epilogue – receive_input • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0xffffd530 %ebp 0x63636363 0x62626262 0x61616161 0x31313131 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 %esp • Function epilogue – receive_input • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0xffffd530 %ebp %esp 0x63636363 0x62626262 0x61616161 0x31313131 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – receive_input • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0xffffd530 %ebp %esp 0x63636363 0x62626262 0x61616161 0x31313131 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – receive_input • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR %esp 0x64646464 0xffffd530 0x63636363 0x62626262 0x61616161 0x31313131 %ebp 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – receive_input • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR %esp 0x64646464 0xffffd530 0x63636363 0x62626262 0x61616161 0x31313131 %ebp 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – receive_input • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… %esp get_a_shell() RET_ADDR 0x64646464 0xffffd530 0x63636363 0x62626262 0x61616161 0x31313131 %ebp 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – receive_input • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… %esp get_a_shell() RET_ADDR 0x64646464 0xffffd530 0x63636363 0x62626262 0x61616161 0x31313131 %ebp 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – run() • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… %esp get_a_shell() RET_ADDR 0x64646464 0xffffd530 0x63636363 0x62626262 0x61616161 0x31313131 %ebp 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – run() • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0xffffd530 0x63636363 0x62626262 0x61616161 0x31313131 %esp %ebp 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – run() • leave • mov %ebp, %esp • pop %ebp • ret
Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0xffffd530 0x63636363 0x62626262 0x61616161 0x31313131 %esp %ebp 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – run() • leave • mov %ebp, %esp • pop %ebp • ret
0x31313131 %ebp Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0xffffd530 0x63636363 0x62626262 0x61616161 %esp 0x31313131 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – run() • leave • mov %ebp, %esp • pop %ebp • ret
0x31313131 %ebp Frame Pointer Attack NO ARG… get_a_shell() RET_ADDR 0x64646464 0xffffd530 0x63636363 0x62626262 0x61616161 %esp 0x31313131 0xffffd530 Buffer at ebp-0x10 ARG1: 41414141 • Function epilogue – run() • leave • mov %ebp, %esp • pop %ebp • ret