CSE351 L15 Buffoverflow - 20sp Ink
CSE351 L15 Buffoverflow - 20sp Ink
Buffer Overflows
CSE 351 Spring 2020
Instructor: Teaching Assistants:
Ruth Anderson Alex Olshanskyy Callum Walker Chin Yeoh
Connie Wang Diya Joy Edan Sneh
Eddy (Tianyi) Zhou Eric Fan Jeffery Tian
Jonathan Chen Joseph Schafer Melissa Birchfield
Millicent Li Porter Jones Rehaan Bhimani
http://xkcd.com/2291/
L15: Buffer Overflows CSE351, Spring 2020
Administrivia
Lab 2 (x86‐64) due TONIGHT, Friday (5/01)
Since you are submitting a text file (defuser.txt), there
won’t be any Gradescope autograder output this time
Extra credit needs to be submitted to the extra credit
assignment
Unit Summary #2, due Friday (5/08)
Lab 3 coming soon!
You will have everything you need by the end of this lecture
You must log on with your @uw google account to access!!
Google doc for 11:30 Lecture: https://tinyurl.com/351‐05‐01A
Google doc for 2:30 Lecture: https://tinyurl.com/351‐05‐01B
2
L15: Buffer Overflows CSE351, Spring 2020
Buffer Overflows
Address space layout (more details!)
Input buffers on the stack
Overflowing buffers and injecting code
Defenses against buffer overflows
3
L15: Buffer Overflows CSE351, Spring 2020
int global = 0;
Heap
int useless() { return 0; }
int main()
{
void *p1, *p2, *p3, *p4; Shared
int local = 0; Libraries
p1 = malloc(1L << 28); /* 256 MB */
p2 = malloc(1L << 8); /* 256 B */
p3 = malloc(1L << 32); /* 4 GB */
p4 = malloc(1L << 8); /* 256 B */ Heap
/* Some print statements ... */
} Data
Instructions
Where does everything go?
6
L15: Buffer Overflows CSE351, Spring 2020
int global = 0;
Heap
int useless() { return 0; }
int main()
{
void *p1, *p2, *p3, *p4; Shared
int local = 0; Libraries
p1 = malloc(1L << 28); /* 256 MB */
p2 = malloc(1L << 8); /* 256 B */
p3 = malloc(1L << 32); /* 4 GB */
p4 = malloc(1L << 8); /* 256 B */ Heap
/* Some print statements ... */
} Data
Instructions
Where does everything go?
7
L15: Buffer Overflows CSE351, Spring 2020
What Is a Buffer?
A buffer is an array used to temporarily store data
8
L15: Buffer Overflows CSE351, Spring 2020
10
L15: Buffer Overflows CSE351, Spring 2020
Higher Addresses
Buffer Overflow in a Nutshell 00
00
Stack grows down towards lower 00
addresses Return 00
Address 00
40
Buffer grows up towards higher dd
addresses bf
buf[7]
stack! 'l'
'l'
Enter input: hello 'e'
buf[0] 'h'
No overflow Lower Addresses 11
L15: Buffer Overflows CSE351, Spring 2020
Higher Addresses
Buffer Overflow in a Nutshell 00
00
Stack grows down towards lower 00
addresses Return 00
Address 00
40
Buffer grows up towards higher dd
addresses bf
buf[7]
Higher Addresses
Buffer Overflow in a Nutshell 00
00
Stack grows down towards lower 00
addresses Return 00
Address '\0'
'f'
Buffer grows up towards higher 'e'
addresses 'd'
buf[7] 'c'
'b'
If we write past the end of the 'a'
array, we overwrite data on the 'o'
stack! 'l'
'l'
Enter input: helloabcdef 'e'
buf[0] 'h'
Buffer overflow! Lower Addresses 13
L15: Buffer Overflows CSE351, Spring 2020
15
L15: Buffer Overflows CSE351, Spring 2020
void call_echo() {
echo();
}
unix> ./buf-nsp
Enter string: 123456789012345
123456789012345
call_echo:
00000000004005c3 <call_echo>:
4005c3: 48 83 ec 08 sub $0x8,%rsp
4005c7: b8 00 00 00 00 mov $0x0,%eax
4005cc: e8 c6 ff ff ff callq 400597 <echo>
4005d1: 48 83 c4 08 add $0x8,%rsp
4005d5: c3 retq
return address 18
L15: Buffer Overflows CSE351, Spring 2020
19
L15: Buffer Overflows CSE351, Spring 2020
8 bytes unused
⟵%rsp
20
L15: Buffer Overflows CSE351, Spring 2020
8 bytes unused
⟵%rsp
unix> ./buf-nsp
Note: Digit “𝑁” is Enter string: 123456789012345
just 0x3𝑁 in ASCII! 123456789012345
Overflowed buffer, but did not corrupt state
21
L15: Buffer Overflows CSE351, Spring 2020
8 bytes unused
⟵%rsp
unix> ./buf-nsp
Enter string: 1234567890123456
Illegal instruction
Overflowed buffer and corrupted return pointer
22
L15: Buffer Overflows CSE351, Spring 2020
23
L15: Buffer Overflows CSE351, Spring 2020
Low Addresses
Input string contains byte representation of executable code
Overwrite return address A with address of buffer B
When bar() executes ret, will jump to exploit code
24
L15: Buffer Overflows CSE351, Spring 2020
Example: Heartbleed
28
L15: Buffer Overflows CSE351, Spring 2020
Example: Heartbleed
29
L15: Buffer Overflows CSE351, Spring 2020
Example: Heartbleed
30
L15: Buffer Overflows CSE351, Spring 2020
Heartbleed (2014)
Buffer over‐read in OpenSSL
Open source security library
Bug in a small range of versions
“Heartbeat” packet
Specifies length of message
Server echoes it back
Library just “trusted” this length
Allowed attackers to read contents
of memory anywhere they wanted
Est. 17% of Internet affected
“Catastrophic”
Github, Yahoo, Stack Overflow, By FenixFeather ‐ Own work, CC BY‐SA 3.0,
Amazon AWS, ... https://commons.wikimedia.org/w/index.php?curid=32276981
31
L15: Buffer Overflows CSE351, Spring 2020
Hacking Cars
UW CSE research from 2010 demonstrated wirelessly
hacking a car using buffer overflow
Overwrote the onboard control system’s code
Disable brakes
Unlock doors
Turn engine on/off
32
L15: Buffer Overflows CSE351, Spring 2020
33
L15: Buffer Overflows CSE351, Spring 2020
1) System‐Level Protections
Non‐executable code segments Stack after call
to gets()
In traditional x86, can mark
foo
region of memory as either stack
“read‐only” or “writeable” frame
1) System‐Level Protections
Stack after call
Non‐executable code segments to gets()
Wait, doesn’t this fix everything? foo
Works well, but can’t always use it stack
frame
Many embedded devices do not
B
have this protection
Cars data written pad bar
stack
Smart homes by gets()
frame
exploit
Pacemakers code
B
Some exploits still work!
Return‐oriented programming
Return to libc attack
JIT‐spray attack
Any attempt to execute this code will fail
35
L15: Buffer Overflows CSE351, Spring 2020
37
L15: Buffer Overflows CSE351, Spring 2020
38
L15: Buffer Overflows CSE351, Spring 2020
3) Stack Canaries
Basic Idea: place special value (“canary”) on stack just
beyond buffer
Secret value that is randomized before main()
Placed between buffer and return address
Check for corruption before exiting function
GCC implementation
-fstack-protector
This is extra
Protected Buffer Disassembly (buf) (non‐testable)
material
echo:
400607: sub $0x18,%rsp
40060b: mov %fs:0x28,%rax
400614: mov %rax,0x8(%rsp)
400619: xor %eax,%eax
... ... call printf ...
400625: mov %rsp,%rdi
400628: callq 400510 <gets@plt>
40062d: mov %rsp,%rdi
400630: callq 4004d0 <puts@plt>
400635: mov 0x8(%rsp),%rax
40063a: xor %fs:0x28,%rax
400643: jne 40064a <echo+0x43>
400645: add $0x18,%rsp
400649: retq
40064a: callq 4004f0 <__stack_chk_fail@plt>
40
L15: Buffer Overflows CSE351, Spring 2020
This is extra
Setting Up Canary (non‐testable)
material
Before call to gets
/* Echo Line */
Stack frame for void echo()
call_echo {
char buf[8]; /* Way too small! */
gets(buf);
Return address puts(buf);
(8 bytes) }
Segment register
echo: (don’t worry about it)
. . .
Canary movq %fs:40, %rax # Get canary
(8 bytes) movq %rax, 8(%rsp) # Place on stack
xorl %eax, %eax # Erase canary
[7] [6] [5] [4] . . .
[3] [2] [1] [0] buf ⟵%rsp
41
L15: Buffer Overflows CSE351, Spring 2020
This is extra
Checking Canary (non‐testable)
material
After call to gets
/* Echo Line */
Stack frame for void echo()
call_echo {
char buf[8]; /* Way too small! */
gets(buf);
Return address puts(buf);
(8 bytes) }
echo:
. . .
movq 8(%rsp), %rax # retrieve from Stack
Canary xorq %fs:40, %rax # compare to canary
(8 bytes) jne .L4 # if not same, FAIL
. . .
00 37 36 35 .L4: call __stack_chk_fail
34 33 32 31 buf ⟵%rsp
Input: 1234567
42
L15: Buffer Overflows CSE351, Spring 2020
43
L15: Buffer Overflows CSE351, Spring 2020
44
L15: Buffer Overflows CSE351, Spring 2020
This is extra
Extra Notes about %rbp (non‐testable)
material
45