700 likes | 847 Vues
This document delves into the mechanics of buffer overflow attacks, with an emphasis on frame pointer manipulation and its implications for system security. It explores how attackers can exploit vulnerabilities to overwrite return addresses and gain unauthorized shell access through carefully crafted input. The study includes practical examples detailing the memory addresses used, various assembly instructions involved, and the role of stack frames in the exploitation process. It serves as a comprehensive guide for cybersecurity professionals seeking to enhance their understanding of attack vectors and defenses.
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