Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 9

Module: Race Conditions

Races in the Filesystem


Yan Shoshitaishvili
Arizona State University
#
Exploiting Race Conditions
Attackers exploit a race condition by changing the state that a program is running in
while the program assumes that this state has not changed.

initialize()

check_input()
ATTACK
do_action()

terminate()

To exploit a race condition, attackers must be able to impact said


environment.
One common case are Races in the Filesystem.
#
The Filesystem
The filesystem is a part of the program state that the attacker can often influence.
Consider:
01 int main(int argc, char **argv) {
02 int fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0755);
03 write(fd, "#!/bin/sh\necho SAFE\n", 20);
04 close(fd);
05 execl("/bin/sh", "/bin/sh", argv[1], NULL);
06 }

Huge window of opportunity: any point between open()


and full startup of /bin/sh is an attack window.
Let's exploit this!
#
Upping the Challenge
What if we make it less winnable?
Consider:
01 int main(int argc, char **argv) {
02 int echo_fd = open("/bin/echo", O_RDONLY);
03 int fd = open(argv[1], O_WRONLY | O_CREAT, 0755);
04 sendfile(fd, echo_fd, 0, 1024*1024);
05 close(fd);
06 execl(argv[1], argv[1], "SAFE", NULL);
07 }

Much smaller window of opportunity...


How do we exploit it? General idea: slow down the victim as
much as possible to make the vulnerable window open longer.
#
Playing Nice
One method: nice
The Linux kernel's scheduler supports different priorities for different programs. The
nice command (and nice() system call) expose this functionality.
Intensive commands might normally interfere with the rest of your system:
$ /usr/bin/intensive_command
Using nice, they can be made to behave better:
$ nice /usr/bin/intensive_command
nice is for CPU, while ionice is for I/O. Using them in combination
can slow down programs enough to win races!
#
Path Complexity
Filesystem races involve filesystem access, and not all filesystem access is equal... For
example:
$ cat my_file
Is much faster than:
$ cat a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/my_file
Why? The kernel takes time to go into all these directories!
We can pass in SUPER long paths to slow the program down (Linux
has a path size limit of 4096 bytes).
#
Filesystem Mazes
Can we do better than 4096 bytes? YES, by using symbolic links!
/my/maze/a/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/root
a_end
b/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/root
b_end
c/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/root
c_end
d/1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/root
d_end

Then we can use paths like /my/maze/a_end/root/b_end/root/c_end/root/d_end/root/some_file


to reference /my/maze/some_file through a huge number of directory
traversals.
Note: Linux has a limit of 40 symbolic links per path resolution.
#
TOCTOU
These types of race conditions tend to show up as Time of Check to Time of Use
vulnerabilities (TOCTOU / TOCTTOU). Example: CVE-2019-7307
The culprit: Ubuntu's crash reporting program (apport)
The bug:

The exploit:
1. Make sure ifpath is accessible to trigger the else condition.
2. Quickly symlink ifpath to something else.
Can be used to read arbitrary files on the filesystem!
#
Mitigations
1. Safer programming practices (O_NOFOLLOW, mkstemp(), etc).
2. Symlink protections in /tmp
a. root cannot follow symlinks in /tmp that are owned by other users
b. specifically made to prevent these sorts of issues

You might also like