CS 519419 Cyber Attacks Defense Yeongjin Jang 100418
CS 519/419 Cyber Attacks & Defense Yeongjin Jang 10/04/18
Points to somewhere up… NO ARG… Buffer Overflow get_a_shell() %ebp • 4 byte buffer… • What if you type “ 1111 aaaabbbbccccddddeeee”? • Overwrites the return address! 0 x 6464 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 0 x 3131 • Can you set that as the address of • get_a_shell()? %esp ARG 1: 4141
Points to somewhere up… NO ARG… Buffer Overflow • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret get_a_shell() %ebp 0 x 6464 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
Points to somewhere up… NO ARG… Buffer Overflow • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret get_a_shell() %ebp %esp 0 x 6464 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
Points to somewhere up… NO ARG… Buffer Overflow • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret get_a_shell() %esp %ebp 0 x 6464 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
Points to somewhere up… Buffer Overflow %ebp: 0 x 6464, INVALID %esp • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret NO ARG… get_a_shell() 0 x 6464 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
Points to somewhere up… Buffer Overflow • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret Run get_a_shell()! %ebp: 0 x 6464, INVALID %esp NO ARG… get_a_shell() 0 x 6464 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
Points to somewhere up… NO ARG… Function Epilogue • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret RET_ADDR %ebp Saved %ebp 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
Points to somewhere up… Function Epilogue %ebp • Function return of receive_input %esp add $0 x 54, %esp Move %esp back to the previous point… pop %esi pop %ebp Buffer at ebp-0 x 10 ret NO ARG… get_a_shell() RET_ADDR 0 x 6464 Saved %ebp 0 x 6363 0 x 6262 0 x 6161 0 x 3131 ARG 1: 4141
Points to somewhere up… NO ARG… Function Epilogue - leave • Function return of receive_input leave ret • The leave instruction mov %ebp, %esp pop %ebp get_a_shell() RET_ADDR %ebp 0 x 6464 Saved %ebp 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
Points to somewhere up… NO ARG… Function Epilogue - leave • Function return of receive_input leave ret • Function return of receive_input leave mov %ebp, %esp pop %ebp ret get_a_shell() RET_ADDR %ebp 0 x 6464 Saved %ebp 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
Points to somewhere up… NO ARG… Function Epilogue - leave • Function return of receive_input leave ret • Function return of receive_input leave mov %ebp, %esp pop %ebp ret get_a_shell() RET_ADDR %ebp 0 x 6464 Saved %ebp 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
Points to somewhere up… NO ARG… Function Epilogue - leave • Function return of receive_input leave ret • Function return of receive_input leave mov %ebp, %esp pop %ebp ret get_a_shell() RET_ADDR %esp %ebp 0 x 6464 Saved %ebp 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
Points to somewhere up… NO ARG… Function Epilogue - leave • Function return of receive_input leave ret • Function return of receive_input leave mov %ebp, %esp pop %ebp ret get_a_shell() RET_ADDR %esp %ebp 0 x 6464 Saved %ebp 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
%ebp Points to somewhere up… NO ARG… Function Epilogue - leave %esp • Function return of receive_input leave ret • Function return of receive_input leave mov %ebp, %esp pop %ebp ret get_a_shell() RET_ADDR 0 x 6464 Saved %ebp 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
%ebp Function Epilogue - leave • Function return of receive_input leave ret • Function return of receive_input leave mov %ebp, %esp pop %ebp ret Points to somewhere up… %esp NO ARG… get_a_shell() RET_ADDR 0 x 6464 Saved %ebp 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • The %ebp register get_a_shell() RET_ADDR %ebp • %esp points to one end of a function’s stack • %ebp points to the other end of a function’s stack 0 x 6464 Saved %ebp 0 x 6363 0 x 6262 0 x 6161 • A function’s Stack Frame • Starts with %ebp • Ends with %esp Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • What if an attacker can… get_a_shell() RET_ADDR %ebp • Overwrite saved %ebp • But cannot overwrite return address? 0 x 6464 Saved %ebp 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • What if an attacker can… get_a_shell() RET_ADDR %ebp • Overwrite saved %ebp • But cannot overwrite return address? 0 x 6464 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • What if an attacker can… get_a_shell() RET_ADDR %ebp • Overwrite saved %ebp • But cannot overwrite return address? 0 x 6464 0 x 6363 0 x 6262 0 x 6161 • Function epilogue Buffer at ebp-0 x 10 0 x 3131 • leave • mov %ebp, %esp • pop %ebp • ret %esp ARG 1: 4141
NO ARG… Frame Pointer Attack • What if an attacker can… get_a_shell() RET_ADDR %ebp • Overwrite saved %ebp • But cannot overwrite return address? 0 x 6464 0 x 6363 0 x 6262 0 x 6161 • Function epilogue Buffer at ebp-0 x 10 0 x 3131 • leave • mov %ebp, %esp • pop %ebp • ret %esp ARG 1: 4141
NO ARG… Frame Pointer Attack • What if an attacker can… get_a_shell() RET_ADDR %esp %ebp • Overwrite saved %ebp • But cannot overwrite return address? 0 x 6464 0 x 6363 0 x 6262 0 x 6161 • Function epilogue Buffer at ebp-0 x 10 0 x 3131 • leave • mov %ebp, %esp • pop %ebp • ret ARG 1: 4141
NO ARG… Frame Pointer Attack • What if an attacker can… get_a_shell() RET_ADDR %esp %ebp • Overwrite saved %ebp • But cannot overwrite return address? 0 x 6464 0 x 6363 0 x 6262 0 x 6161 • Function epilogue Buffer at ebp-0 x 10 0 x 3131 • leave • mov %ebp, %esp • pop %ebp • ret ARG 1: 4141
%ebp 0 x 6464 NO ARG… Frame Pointer Attack %esp • What if an attacker can… get_a_shell() RET_ADDR 0 x 6464 0 x 6363 • Overwrite saved %ebp • But cannot overwrite return address? 0 x 6262 0 x 6161 • Function epilogue Buffer at ebp-0 x 10 0 x 3131 • leave • mov %ebp, %esp • pop %ebp • ret ARG 1: 4141
%ebp 0 x 6464 NO ARG… Frame Pointer Attack %esp • What if an attacker can… get_a_shell() RET_ADDR 0 x 6464 0 x 6363 • Overwrite saved %ebp • But cannot overwrite return address? 0 x 6262 0 x 6161 • Function epilogue Buffer at ebp-0 x 10 0 x 3131 • leave • mov %ebp, %esp • pop %ebp • ret ARG 1: 4141
%ebp Frame Pointer Attack 0 x 6464 %esp NO ARG… get_a_shell() RET_ADDR 0 x 6464 • What if an attacker can… 0 x 6363 • Overwrite saved %ebp • But cannot overwrite return address? 0 x 6262 0 x 6161 • Function epilogue Buffer at ebp-0 x 10 0 x 3131 • leave • mov %ebp, %esp • pop %ebp • ret • Return to the correct RET_ADDR • Is it problematic? ? ARG 1: 4141
%ebp Frame Pointer Attack 0 x 6464 %esp NO ARG… get_a_shell() RET_ADDR 0 x 6464 • Call chain (in bof-level 5) • main() -> run() -> receive_input() • We just ran leave-ret in receive_input() Buffer at ebp-0 x 10 0 x 6363 0 x 6262 0 x 6161 0 x 3131 • There will be another leave-ret in run() • What will happen if that runs? ? ? ARG 1: 4141
%ebp Frame Pointer Attack 0 x 6464 %esp • main() -> run() -> receive_input() 0 x 6363 0 x 6262 0 x 6161 • leave-ret in run() • mov %ebp, %esp • pop %ebp get_a_shell() RET_ADDR 0 x 6464 • Call chain (in bof-level 5) • leave NO ARG… Buffer at ebp-0 x 10 0 x 3131 • ret ARG 1: 4141
%ebp Frame Pointer Attack 0 x 6464 %esp • main() -> run() -> receive_input() 0 x 6363 0 x 6262 0 x 6161 • leave-ret in run() • mov %ebp, %esp • pop %ebp get_a_shell() RET_ADDR 0 x 6464 • Call chain (in bof-level 5) • leave NO ARG… Buffer at ebp-0 x 10 0 x 3131 • ret ARG 1: 4141
%esp %ebp 0 x 6464 NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 • Call chain (in bof-level 5) • main() -> run() -> receive_input() • mov %ebp, %esp • pop %ebp 0 x 6262 0 x 6161 • leave-ret in run() • leave 0 x 6363 Buffer at ebp-0 x 10 0 x 3131 • ret ARG 1: 4141
%esp %ebp 0 x 6464 NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 • Call chain (in bof-level 5) • main() -> run() -> receive_input() • mov %ebp, %esp • pop %ebp • ret 0 x 6262 0 x 6161 • leave-ret in run() • leave 0 x 6363 Buffer at ebp-0 x 10 Invalid Address 0 x 6464!! %esp = 0 x 6464 pop %ebp -> mov (%esp), %ebp add $4, %esp 0 x 3131 ARG 1: 4141
GDB, break at receive_input’s leave dddd = 0 x 6464 Leave mov %ebp, %esp pop %ebp %esp = 0 xffffd 56 c %ebp = 0 x 6464
GDB, break at receive_input’s leave dddd = 0 x 6464 Leave mov %ebp, %esp pop %ebp %esp = 0 xffffd 56 c %ebp = 0 x 6464
GDB, break at run’s leave dddd = 0 x 6464 Leave mov %ebp, %esp pop %ebp <- fault! %esp = 0 x 6464 %ebp = 0 x 6464
GDB, break at run’s leave dddd = 0 x 6464 Leave mov %ebp, %esp pop %ebp <- fault! %esp = 0 x 6464 %ebp = 0 x 6464
Exploiting Frame Pointer • We can change the saved %ebp • The %ebp of a function in the upper level • main() -> run() -> receive_input() • If that is invalid address such as 0 x 6464 • Will generate SIGSEGV, a segmentation fault • What if we put a valid address on it? ? • The address that we can control…
NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR • Let’s put a stack address at saved %ebp… %ebp 0 x 6363 0 x 6262 • Suppose our original %ebp = 0 xffffd 540 • ebp-0 x 10 = 0 xffffd 530 0 x 6464 0 xffffd 530 0 x 6161 0 xffffd 530 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • Function epilogue – receive_input get_a_shell() RET_ADDR %ebp • leave 0 x 6363 0 x 6262 • mov %ebp, %esp • pop %ebp • ret 0 x 6464 0 xffffd 530 0 x 6161 0 xffffd 530 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • Function epilogue – receive_input get_a_shell() RET_ADDR %ebp • leave 0 x 6363 0 x 6262 • mov %ebp, %esp • pop %ebp • ret 0 x 6464 0 xffffd 530 0 x 6161 0 xffffd 530 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • Function epilogue – receive_input get_a_shell() RET_ADDR %esp %ebp • leave 0 x 6363 0 x 6262 • mov %ebp, %esp • pop %ebp • ret 0 x 6464 0 xffffd 530 0 x 6161 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • Function epilogue – receive_input get_a_shell() RET_ADDR %esp %ebp • leave 0 x 6363 0 x 6262 • mov %ebp, %esp • pop %ebp • ret 0 x 6464 0 xffffd 530 0 x 6161 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR %esp • Function epilogue – receive_input 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret 0 x 6464 0 xffffd 530 0 x 6161 %ebp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR %esp • Function epilogue – receive_input 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret 0 x 6464 0 xffffd 530 0 x 6161 %ebp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
Frame Pointer Attack %esp get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – receive_input 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret NO ARG… 0 x 6161 %ebp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
Frame Pointer Attack %esp get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run() 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret NO ARG… 0 x 6161 %ebp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
Frame Pointer Attack %esp get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run() 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret NO ARG… 0 x 6161 %ebp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run() 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret %esp %ebp 0 x 6161 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run() 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret %esp %ebp 0 x 6161 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
0 x 3131 %ebp NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run() 0 x 6363 • leave • mov %ebp, %esp • pop %ebp • ret 0 x 6262 %esp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 6161 0 x 3131 ARG 1: 4141
0 x 3131 %ebp NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run() 0 x 6363 • leave • mov %ebp, %esp • pop %ebp • ret 0 x 6262 %esp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 6161 0 x 3131 ARG 1: 4141
0 x 3131 %ebp NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run() 0 x 6363 • leave • mov %ebp, %esp • pop %ebp • ret 0 x 6262 %esp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 6161 0 x 3131 • Where? ? ? ARG 1: 4141
0 x 3131 %ebp NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run() 0 x 6363 • leave • mov %ebp, %esp • pop %ebp • ret %esp 0 x 6262 0 x 6161 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 • Where? ? ? • 0 x 6161! ARG 1: 4141 • Where do you want to put get_a_shell()?
NO ARG… Frame Pointer Attack • Function epilogue – receive_input get_a_shell() RET_ADDR %ebp • leave 0 x 6363 0 x 6262 • mov %ebp, %esp • pop %ebp • ret 0 x 6464 0 xffffd 530 get_a_shell() 0 xffffd 530 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • Function epilogue – receive_input get_a_shell() RET_ADDR %ebp • leave 0 x 6363 0 x 6262 • mov %ebp, %esp • pop %ebp • ret 0 x 6464 0 xffffd 530 get_a_shell() 0 xffffd 530 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • Function epilogue – receive_input get_a_shell() RET_ADDR %esp %ebp • leave 0 x 6363 0 x 6262 • mov %ebp, %esp • pop %ebp • ret 0 x 6464 0 xffffd 530 get_a_shell() 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack • Function epilogue – receive_input get_a_shell() RET_ADDR %esp %ebp • leave 0 x 6363 0 x 6262 • mov %ebp, %esp • pop %ebp • ret 0 x 6464 0 xffffd 530 get_a_shell() 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack %esp • Function epilogue – receive_input 0 x 6464 0 xffffd 530 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret get_a_shell() RET_ADDR get_a_shell() %ebp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack %esp • Function epilogue – receive_input 0 x 6464 0 xffffd 530 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret get_a_shell() RET_ADDR get_a_shell() %ebp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
Frame Pointer Attack %esp get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – receive_input 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret NO ARG… get_a_shell() %ebp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
Frame Pointer Attack %esp get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret NO ARG… get_a_shell() %ebp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret %esp %ebp get_a_shell() 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run 0 x 6363 • leave 0 x 6262 • mov %ebp, %esp • pop %ebp • ret %esp %ebp get_a_shell() 0 xffffd 530 Buffer at ebp-0 x 10 0 x 3131 ARG 1: 4141
%ebp 0 x 3131 NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run 0 x 6363 • leave • mov %ebp, %esp • pop %ebp • ret 0 x 6262 %esp 0 xffffd 530 Buffer at ebp-0 x 10 get_a_shell() 0 x 3131 ARG 1: 4141
%ebp 0 x 3131 NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run 0 x 6363 • leave • mov %ebp, %esp • pop %ebp • ret 0 x 6262 %esp 0 xffffd 530 Buffer at ebp-0 x 10 get_a_shell() 0 x 3131 ARG 1: 4141
%ebp 0 x 3131 NO ARG… Frame Pointer Attack get_a_shell() RET_ADDR 0 x 6464 0 xffffd 530 • Function epilogue – run 0 x 6363 • leave • mov %ebp, %esp • pop %ebp • ret %esp 0 xffffd 530 Buffer at ebp-0 x 10 0 x 6262 get_a_shell() 0 x 3131 • Run get_a_shell()!!!! ARG 1: 4141
Frame Pointer Attack • You can change the upper function’s return address via saved %ebp • Formula • Set saved %ebp as some_address_of_your_input • Set the value at some_address_of_your_input+4 as return target • Why +4? • leave: mov %ebp, %esp; pop %ebp esp gets +4 • ret!
Assignment: Week-2 • Please solve challenges in the /home/labs/week 2 directory • Level 5 – can overwrite saved %ebp • Level 6 – can overwrite saved %rbp • Level 7 – can overwrite only 1 byte of saved %ebp • Level 8 – can overwrite only 1 byte of saved %rbp • Level 9 – can overwrite saved %rbp, but main returns in weird way… • Due: 10/11 2: 00 pm
- Slides: 67