On Oct. 11, a new version of curl (8.4.0) was released where a couple of new vulnerabilities were fixed (CVE-2023-38545 with severity HIGH and CVE-2023-38546 with severity LOW). These issues were previously announced in the project’s discussion. At the time of this blog, there have been several proof of concepts released for CVE-2023-38545 which result in crashes, but not exploitation.
- CVE-2023-38545 is a SOCKS5 heap buffer overflow. This flaw makes curl overflow a heap-based buffer in the SOCKS5 proxy handshake.
- CVE-2023-38546 is a cookie injection with a file named none. This flaw allows an attacker to insert cookies at will into a running program, using libcurl, if a specific series of conditions are met.
In the words of the researcher who discovered CVE-2023-38545:
“If the state machine is delayed, then the resolution is made remotely with a malformed SOCKS packet. The attacker has written to the heap and likely overwritten in-use data that comes after
data->state.buffer. It’s undefined behavior at best and possible RCE at worst.”
The versions affected by the CVE-2023-38545 are:
- libcurl 7.69.0 up to and including 8.3.0 (introduced in the following commit)
- Versions not affected: libcurl < 7.69.0 and >= 8.4.0
In this article, we’ll explain CVE-2023-38545, how it is exploited, and how to detect it.
For successful exploitation of CVE-2023-38545, there are some requirements that must be met when the target is the curl binary (as opposed to libcurl):
- Curl needs to try and use a domain name of excessive size
- The SOCKS setting need to include ––
socks5-hostname, or –proxy or –preproxy set to use the scheme
- The CURLOPT_BUFFERSIZE environment variable is either not set or is set smaller than 65541
The vulnerability also exists in the library version of curl, called libcurl. This library can be included in any program, which can make detection challenging as the above conditions can be set within the program itself and are generally not visible to security tools.
How the vulnerability works
The vulnerability exists due to a logic flaw in the way the
do_SOCKS5 function is implemented. The function implements a state machine to handle all of the logic, from connecting to the proxy server to the final request. Given that the specification for the SOCKS5H socks proxy states that the remote resolution of a hostname can be a maximum of 255 characters. This check is performed by
do_SOCKS5 in the first state, called
CONNECT_SOCKS_INIT, without taking into account that we can exit the state machine at any time within
CONNECT_SOCKS_READ by introducing a forced delay during the reception of the “hello” packet for the server. This causes the socket to remain in a pending state.
On subsequent calls to
do_SOCKS5, the variable
socks5_resolve_local, which controls whether the request should be resolved locally or remotely, is set to its previous state (FALSE). As we are no longer in
CONNECTION_SOCKS_INIT state, no further checks are made to ensure that the hostname is not longer than 255 characters, leading to a heap buffer overflow.
For more information, the researcher who made the discovery published a complete walkthrough.
CVE-2023-38545 Exploitation Challenges
As of this blog’s publication, successful exploitation of this vulnerability will be difficult due to a number of factors:
- The attacker will need to control the destination server to cause an HTTP 30X redirect to a very long domain name in order to overflow the buffer. Alternatively, the attacker will need to be able to control the domain name passed to curl in order to point it to a malicious server or otherwise pass in the overflowing data.
- The dynamic memory allocation in the heap can change dynamically at any run, making it difficult to predict the exact location of the data you want to manipulate or overwrite.
- Since this is a remotely exploited vulnerability, there is no consistent memory leak that can be used to bypass ASLR (Address Space Layout Randomization) memory protection. The attacker would also not know what objects are allocated in memory near the buffer on which we are overflowing to successfully gain execution.
There are two use cases to address when trying to detect this vulnerability. For detection, we will use the open source tool Falco. The first case is if the curl binary itself is the target of exploitation. It is not practical to detect the exploitation code in the network packets or data, but we can make a behavioral rule.
In the rule below, we detect processes which are launched that have curl as a parent process and where curl is using SOCKS5. Curl typically doesn’t launch processes, so this could be an indication of a breach.
- macro: curl_pname_socks
condition: proc.pcmdline contains " --socks" or proc.pcmdline contains " -x socks" or proc.pcmdline contains " --preproxy socks" or proc.env icontains "all_proxy=socks" or proc.env icontains "https_proxy=socks" or proc.env icontains "http_proxy=socks"
- rule: Curl with Socks options opening processes
desc: Detect a curl command with socks options spawning processes
condition: spawned_process and proc.pname=curl and (curl_pname_socks)
output: A curl command with Socks options has just spawned a new process (proc.name=%proc.name proc.pname=%proc.pname proc.cmdline=%proc.cmdline proc.pcmdline=%proc.pcmdline proc.env=%proc.env gparent=%proc.aname ggparent=%proc.aname gggparent=%proc.aname proc.sid=%proc.sid proc.exepath=%proc.exepath user.uid=%user.uid user.loginname=%user.loginname group.gid=%group.gid group.name=%group.name container.name=%container.name image=%container.image.repository)
tags: [host, container, CVE-2023-38545]
Code language: Perl (perl)
In the case of libcurl being exploited, it is even more difficult to detect since the library could be used in any process. In this case, we recommend more generic threat detection rules that detect post-exploitation behavior. While the way in which the program is exploited might be different, the attacker’s follow-on actions are usually the same.
- Run shell untrusted
- Search Private Keys or Passwords
- Redirect STDOUT/STDIN to Network Connection in Container
- Fileless execution via memfd_create
- Adding ssh keys to authorized_keys
The recently announced high severity vulnerability in curl is of concern, as it could result in remote code execution, but is not currently considered critical. Exploiting the vulnerability is not trivial and requires an attacker to be able to control the website being visited or the domain name which is passed to curl. It is also complicated by the library version being affected, which makes runtime detection difficult. Instead, we recommend looking for post-exploitation behavior, which is easier to detect and less prone to change.
Sysdig Secure can help you benchmark your Kubernetes cluster and check whether it’s compliant with security standards like PCI or NIST.