Cyber Attacks Defense Buffer Overflow Dr Yeongjin Jang
Cyber Attacks & Defense Buffer Overflow Dr. Yeongjin Jang
Week 1 • Due: 04/13 2: 00 pm • Late submission due: 04/20 2: 00 pm (50% pts) • You will not get any point after this date
Week 2 Objectives • Understand how stack works in Linux x 86/amd 64 ABIs • Understand why buffer overflow could be a security vulnerability • Identify a buffer overflow vulnerability in the program • Exploit a buffer overflow vulnerability to hijack the control of the program
X 86 Stack (pointed by %esp/%rsp) • Stores local variables (negative indexing over ebp) • mov -0 x 8(%ebp), %eax • lea -0 x 24(%ebp), %eax -- value at ebp-0 x 8 -- address at ebp-0 x 24 • Stores function arguments from caller (positive indexing over ebp) • mov 0 x 8(%ebp), %eax • mov 0 xc(%ebp), %eax -- 1 st arg -- 2 nd arg • Pushes function arguments to callee (positive indexing over esp) • mov %eax, 0(%esp) • mov $0 x 4, 0 x 4(%esp) -- 1 st arg -- 2 nd arg
Calling Convention Receiving Func Arguments from Caller • x 86 (32 bit) – pushes argument on the stack (for callee) • • • 0 x 4 * n (%esp) indicates n-th argument 0(%esp) – accessed by callee via 0 x 8(%ebp) 0 x 4(%esp) – accessed by callee via 0 xc(%ebp) 0 x 8(%esp) – accessed by callee via 0 x 10(%ebp) Focus on +0 x 8, +0 xc, +0 x 10, etc. , for the index on %ebp at the callee… • amd 64 (64 bit) – use registers to pass argument to callee • Register order (1 st, 2 nd, 3 rd, 4 th, 5 th, 6 th, etc. ) • %rdi, %rsi, %rdx, %rcx, %r 8, %r 9, … (use stack for more arguments) • Callee also uses these registers to get arguments
Examples printf(0 x 8048727, ebp_8, ebp_c) • printf() in x 86 lea mov mov mov call printf(0 x 400905, rbp_8, rbp_10) • printf() in amd 64 0 x 8048727, %eax -0 x 8(%ebp), %ecx -0 xc(%ebp), %edx 1 st %eax, (%esp) %ecx, 0 x 4(%esp) 2 nd %edx, 0 x 8(%esp) 3 rd 0 x 8048370 <printf@plt> movabs mov callq 1 st $0 x 400905, %rdi -0 x 8(%rbp), %rsi 2 nd -0 x 10(%rbp), %rdx 3 rd 0 x 400500 <printf@plt>
In amd 64 • Stores local variables (negative access over rbp) • mov -0 x 8(%rbp), %rax • lea -0 x 24(%rbp), %rax • Function arguments to callee does not use stack • mov %rax, %rdi • mov $0 x 4, %rsi • mov $0 x 40006, %rdx • Function arguments from caller does not use stack • mov %rdi, %rax • mov %rsi, %rbx amd 64 Calling Convention %rdi – 1 st arg %rsi – 2 nd arg %rdx – 3 rd arg %rcx – 4 th arg %r 8 – 5 th arg %r 9 – 6 th arg It has 16 registers, rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp r 8, r 9, r 10, r 11, r 12, r 13, r 14, r 15
MY_ARG 2 Stack (Grows Downward) • Defines a variable scope of a function %ebp • Local variables (negative index over ebp) • Arguments (positive index over ebp) • Function call arguments (positive index over esp) MY_ARG 1 Return Addr Saved EBP Local A ebp-8 Local B ebp-c Local C ebp-10 ARG 2 esp+4 ARG 1 esp • Maintains nested function calls • Return target (return address) • Local variables of the upper level function (Saved ebp) %esp • Starts at %ebp (bottom), ends at %esp (top)
%ebp Example – Function call Points to somewhere up… %esp • In bof-level 0, main() calls receive_input() • call 0 x 8048570 <receive_input> • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp NO ARG…
%ebp Example – Function call Points to somewhere up… %esp • In bof-level 0, main() calls receive_input() • call 0 x 8048570 <receive_input> • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp NO ARG…
%ebp Example – Function call Points to somewhere up… NO ARG… %esp • In bof-level 0, main() calls receive_input() • call 0 x 8048570 <receive_input> • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp Call: push the address to return to the stack, then jump! push %eip -- points the next instruction jmp 0 x 8048570 <receive_input> Return Addr 0 x 804866 b
%ebp Example – Function call Points to somewhere up… NO ARG… %esp • In bof-level 0, main() calls receive_input() • call 0 x 8048570 <receive_input> • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp Return Addr 0 x 804866 b
%ebp Points to somewhere up… NO ARG… Example – Function call • In bof-level 0, main() calls receive_input() Return Addr 0 x 804866 b %esp • call 0 x 8048570 <receive_input> • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp Saved EBP
%ebp Points to somewhere up… NO ARG… Example – Function call • In bof-level 0, main() calls receive_input() Return Addr 0 x 804866 b %esp • call 0 x 8048570 <receive_input> • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp Saved EBP
Points to somewhere up… NO ARG… Example – Function call • In bof-level 0, main() calls receive_input() Return Addr 0 x 804866 b %ebp %esp • call 0 x 8048570 <receive_input> • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp Saved EBP
Points to somewhere up… NO ARG… Example – Function call • In bof-level 0, main() calls receive_input() Return Addr 0 x 804866 b %ebp %esp • call 0 x 8048570 <receive_input> • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp Saved EBP
Points to somewhere up… NO ARG… Example – Function call • In bof-level 0, main() calls receive_input() Return Addr 0 x 804866 b %ebp • call 0 x 8048570 <receive_input> %esp • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp Saved EBP Saved ESI
Points to somewhere up… NO ARG… Example – Function call • In bof-level 0, main() calls receive_input() Return Addr 0 x 804866 b %ebp • call 0 x 8048570 <receive_input> %esp • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp Saved EBP Saved ESI
Points to somewhere up… NO ARG… Example – Function call • In bof-level 0, main() calls receive_input() Return Addr 0 x 804866 b %ebp • call 0 x 8048570 <receive_input> • 0 x 0804866 b <+11>: xor %eax, %eax • Head of receive_input • • 0 x 08048570 0 x 08048571 0 x 08048573 0 x 08048574 <+0>: push <+1>: mov <+3>: push <+4>: sub %ebp %esp, %ebp %esi $0 x 54, %esp Saved EBP Saved ESI
Points to somewhere up… NO ARG… Example – Function call • Call printf? movl $0 x 4141, -0 x 8(%ebp) movl $0 x 4242, -0 xc(%ebp) lea 0 x 8048727, %eax mov -0 x 8(%ebp), %ecx mov -0 xc(%ebp), %edx mov %eax, (%esp) mov %ecx, 0 x 4(%esp) mov %edx, 0 x 8(%esp) call 0 x 8048370 <printf@plt> Return Addr 0 x 804866 b %ebp %esp Saved EBP Saved ESI
Points to somewhere up… NO ARG… Example – Function call • Call printf? movl $0 x 4141, -0 x 8(%ebp) movl $0 x 4242, -0 xc(%ebp) lea 0 x 8048727, %eax mov -0 x 8(%ebp), %ecx mov -0 xc(%ebp), %edx mov %eax, (%esp) mov %ecx, 0 x 4(%esp) mov %edx, 0 x 8(%esp) call 0 x 8048370 <printf@plt> Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 4141 %esp
Points to somewhere up… NO ARG… Example – Function call • Call printf? movl $0 x 4141, -0 x 8(%ebp) movl $0 x 4242, -0 xc(%ebp) lea 0 x 8048727, %eax mov -0 x 8(%ebp), %ecx mov -0 xc(%ebp), %edx mov %eax, (%esp) mov %ecx, 0 x 4(%esp) mov %edx, 0 x 8(%esp) call 0 x 8048370 <printf@plt> Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 4141 0 x 4242 %esp
Points to somewhere up… NO ARG… Example – Function call • Call printf? movl $0 x 4141, -0 x 8(%ebp) movl $0 x 4242, -0 xc(%ebp) lea 0 x 8048727, %eax mov -0 x 8(%ebp), %ecx mov -0 xc(%ebp), %edx mov %eax, (%esp) mov %ecx, 0 x 4(%esp) mov %edx, 0 x 8(%esp) call 0 x 8048370 <printf@plt> Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 4141 0 x 4242 %esp ARG 1: %x %x
Points to somewhere up… NO ARG… Example – Function call • Call printf? movl $0 x 4141, -0 x 8(%ebp) movl $0 x 4242, -0 xc(%ebp) lea 0 x 8048727, %eax mov -0 x 8(%ebp), %ecx mov -0 xc(%ebp), %edx mov %eax, (%esp) mov %ecx, 0 x 4(%esp) mov %edx, 0 x 8(%esp) call 0 x 8048370 <printf@plt> Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 2: 4141 %esp ARG 1: %x %x
Points to somewhere up… NO ARG… Example – Function call • Call printf? movl $0 x 4141, -0 x 8(%ebp) movl $0 x 4242, -0 xc(%ebp) lea 0 x 8048727, %eax mov -0 x 8(%ebp), %ecx mov -0 xc(%ebp), %edx mov %eax, (%esp) mov %ecx, 0 x 4(%esp) mov %edx, 0 x 8(%esp) call 0 x 8048370 <printf@plt> Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 %esp ARG 1: %x %x
Points to somewhere up… NO ARG… Example – Function call • Call printf? movl $0 x 4141, -0 x 8(%ebp) movl $0 x 4242, -0 xc(%ebp) lea 0 x 8048727, %eax mov -0 x 8(%ebp), %ecx mov -0 xc(%ebp), %edx mov %eax, (%esp) mov %ecx, 0 x 4(%esp) mov %edx, 0 x 8(%esp) call 0 x 8048370 <printf@plt> lea 0 x 8048765, %ecx Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 %esp ARG 1: %x %x
Points to somewhere up… NO ARG… Example – Function call • Call printf? movl $0 x 4141, -0 x 8(%ebp) movl $0 x 4242, -0 xc(%ebp) lea 0 x 8048727, %eax mov -0 x 8(%ebp), %ecx mov -0 xc(%ebp), %edx mov %eax, (%esp) mov %ecx, 0 x 4(%esp) mov %edx, 0 x 8(%esp) call 0 x 8048370 <printf@plt> lea 0 x 8048765, %ecx Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 ARG 1: %x %x %esp Return Addr
Example – Function call 4242 4141 • What printf will see? %d %d %esp Return Addr
Points to somewhere up… Example – Function Return • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret %ebp NO ARG… Return Addr 0 x 804866 b Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 %esp ARG 1: %x %x
Points to somewhere up… Example – Function Return • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret %ebp NO ARG… Return Addr 0 x 804866 b Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 %esp ARG 1: %x %x
Points to somewhere up… Example – Function Return • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret %ebp %esp NO ARG… Return Addr 0 x 804866 b Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 ARG 1: %x %x
Points to somewhere up… Example – Function Return • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret %ebp %esp NO ARG… Return Addr 0 x 804866 b Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 ARG 1: %x %x
Points to somewhere up… Example – Function Return • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret %esp %ebp NO ARG… Return Addr 0 x 804866 b Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 ARG 1: %x %x
Points to somewhere up… Example – Function Return • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret %esp %ebp NO ARG… Return Addr 0 x 804866 b Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 ARG 1: %x %x
Points to somewhere up… %ebp Example – Function Return %esp • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret NO ARG… Return Addr 0 x 804866 b Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 ARG 1: %x %x
Points to somewhere up… %ebp Example – Function Return %esp • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret NO ARG… Return Addr 0 x 804866 b Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 ret: pop %eip, change instruction ptr. . ARG 1: %x %x
%ebp Points to somewhere up… Example – Function Return%esp • Function return of receive_input add $0 x 54, %esp pop %esi pop %ebp ret NO ARG… Return Addr 0 x 804866 b Saved EBP Saved ESI 0 x 4141 0 x 4242 ARG 3: 4242 ARG 2: 4141 call 0 x 8048570 <receive_input> 0 x 0804866 b <+11>: xor %eax, %eax ARG 1: %x %x
Buffer Overflow • Example • char buf[20]; • fgets(buf, 128, stdin);
Points to somewhere up… NO ARG… Buffer Overflow • Overwrite values in stack by overflowing Return Addr 0 x 804866 b %ebp • A local variable buffer • Suppose we have char buffer[4]; • -0 x 8(%ebp) stores 0 x 4141 • -0 xc(%ebp) stroes 0 x 4242 • -0 x 10(%ebp) is a buffer, size 4 byte. Saved EBP Saved ESI 0 x 4141 0 x 4242 Buffer at ebp-0 x 10 Buffer. . • Program gets input from you via • fgets(buffer, 128, stdin); • Read 128 bytes. . • What if you type “ 1111 aaaabbbb”? %esp ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow • 4 byte buffer… • What if you type “ 1111 aaaabbbb”? Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 4141 0 x 4242 Buffer at ebp-0 x 10 %esp Buffer. . ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow • 4 byte buffer… • What if you type “ 1111 aaaabbbb”? Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 4141 0 x 4242 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow • 4 byte buffer… • What if you type “ 1111 aaaabbbb”? Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 4141 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow • 4 byte buffer… • What if you type “ 1111 aaaabbbb”? Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow • 4 byte buffer… • What if you type “ 1111 aaaabbbb”? Return Addr 0 x 804866 b %ebp Saved EBP Saved ESI 0 x 6262 0 x 6161 • You can change variables! Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: %x %x
Points to somewhere up… NO ARG… Return Address • Store the execution points after the call • 0 x 08048666 <+6>: • 0 x 0804866 b <+11>: Return Addr 0 x 804866 b %ebp call 0 x 8048570 <receive_input> xor %eax, %eax Saved EBP Saved ESI 0 x 6262 0 x 6161 • Should store 0 x 804866 b on calling receive_input… Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow Return Addr 0 x 804866 b %ebp • 4 byte buffer… • What if you type “ 1111 aaaabbbbccccddddeeee”? Saved EBP Saved ESI 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow Return Addr 0 x 804866 b %ebp • 4 byte buffer… • What if you type “ 1111 aaaabbbbccccddddeeee”? Saved EBP 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow Return Addr 0 x 804866 b %ebp • 4 byte buffer… • What if you type “ 1111 aaaabbbbccccddddeeee”? 0 x 6464 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow 0 x 6565 %ebp • 4 byte buffer… • What if you type “ 1111 aaaabbbbccccddddeeee”? 0 x 6464 0 x 6363 0 x 6262 0 x 6161 Buffer at ebp-0 x 10 %esp 0 x 3131 ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow 0 x 6565 %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 %esp 0 x 3131 ARG 1: %x %x
Points to somewhere up… NO ARG… Buffer Overflow 0 x 6565 %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: %x %x
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: %x %x
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: %x %x
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: %x %x
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: %x %x
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: %x %x
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: %x %x
Objective of Week 2 Challenges • Identify the size of buffer in the program • Try to overflow the buffer to control local variable/return address values • Run get_a_shell()
Assignment: Week-2 • Please solve challenges in the /home/labs/week 2 directory • Level 0 – change the value of local variables via BOF • Level 1 – the same as level 0 in amd 64 • Level 2 – change the return address to execute get_a_shell() • Level 3 – change the return address to execute get_a_shell(), 64 bit • Level 4 – Defeat a simple defense to return address overwriting • Due: 04/20 2: 00 pm
- Slides: 59