Detecting and Mitigating CVE-2023-4911: Local Privilege Escalation Vulnerability
Published 02/01/2024
Originally published by Sysdig.
Written by Daniele Linguaglossa.
Recently, Qualys discovered and reported a critical vulnerability affecting the popular GLIBC ecosystem, which is installed by default on most Linux-based operating systems. Specifically, a buffer overflow was found in the code responsible for handling special environment variables during the startup of a process which can result in a local privilege escalation. Fortunately, exploitation of this vulnerability can be detected. In this article, we will deep dive into this vulnerability, dubbed ‘Looney Tunables’, to see why it happened and how to detect and mitigate the risk.
The flaw, assigned CVE-2023-4911 with a score of 7.8, is considered a high severity vulnerability. If exploited, the attacker could gain root permission on a Linux installation with GLIBC version 2.34 (see Linux distribution for accurate information on status). At the time of this writing, several proof of concept versions of the exploit have been released. The exploitation itself is straightforward; even with memory address brute forcing involved, successful exploitation could happen in under five minutes.
An attacker begins by modifying the LD_LIBRARY_PATH for a given suid binary or making a copy, allowing processes to load untrusted shared objects from an attacker-controlled directory. This results in the execution of malicious code with root privileges.
Fixes for this vulnerability are currently being released by the various Linux distributions. We recommend you check their sites for fix information, as this vulnerability is affecting many different versions.
Preliminary
GLIBC is installed by default on many popular Linux distributions, such as Ubuntu, Fedora, Red Hat, and Debian. It includes the Linux dynamic loader (ld.so), a piece of software responsible for loading all the needed shared objects for a program to run. Its task can be briefly described as:
- Loading shared libraries
- Symbol resolution
- Performing relocations
- Handling
<em>LD_PRELOAD</em>
andLD_LIBRARY_PATH
environment variables - Mapping the binary in memory
- Memory management
- Running the binary
The vulnerability found by Qualys happens during the initialization of the dynamic linker, specifically the handling of the GLIBC_TUNABLES environment variable. This variable allows for tweaking GLIBC behavior during the subsequent events.
A list of available tunables can be obtained by running the following command:
/lib64/ld-linux-x86-64.so.2 --list-tunables
The tunables must be provided to the target binary as a list of colon-separated key-value pairs during the program execution. The linker is responsible for parsing, and eventually stripping, security sensitive tunables from the environment variables. Below is the in-depth analysis of what happens during tunables parsing and exploitation.
CVE-2023-4991 Details
The flaw was introduced with commit 2ed18c (“Fix SXID_ERASE
behavior in setuid programs (BZ #27471)”) inside __tunables_init
function. When this function is called, it loops through environment variables and searches for GLIBC_TUNABLES. Once found, it calls tunables_strdup
to create a copy of the variable and start to process it. Since GLIBC is not yet initialized, the strdup function uses __minimal_malloc
under the hood, which calls mmap to request memory from the Kernel. This causes the memory to be allocated from virtual memory instead of the heap.
The buffer overflow occurs because of the way the arguments are parsed. If the tunable string is in the format of tunable1=tunable2=value, it will first parse the string as tunable1=”tunable2=value” and later keep processing it as tunable2=value. This will lead to more data being copied inside the allocated buffer than is allowed. Although the vulnerability was discovered by source code auditing, Qualys stated that fuzzing the logic with AFL++ or Libfuzzer was able to reproduce the crash in seconds.
The exploitation technique explained by Qualys is straightforward and consists of filling the environment with NULL bytes until we overflow into the l_info
member of<em>link_map</em>
structure. This structure (<em>Elf64_Dyn</em>
) points to the dynamic section of the binary and is composed of a tag and a value. In this case, we are interested in the DT_RPATH
tag, which is the dynamic section of the binary containing the location where the library lookup is performed.
Carefully crafting a payload which modifies that pointer could lead to the binary loading shared objects from untrusted directories, and that’s a major issue when it comes to setuid binaries.
The current exploitation techniques won’t bypass ASLR and are based on brute-force guessing. Considering the stack is allocated 16GB of memory, the process environment can occupy up to 6MB, and the chosen pointer points exactly in the middle of the stack, there’s a good chance that the pointer will be valid after 2,730 tries. In a loop on a host, this takes mere minutes.
Detecting CVE-2023-4911
To reach the vulnerable code, an exploit has to pass data through a particular environment variable GLIBC_TUNABLES, which can be observed by cloud-native security tools. To decrease the risk of false positives, you can also look for a segmentation fault signal when the process crashes. As previously mentioned, the exploit brute forces its way to the proper memory address, so any failure will result in a segmentation fault (a.k.a. crash).
<code>- rule: GLIBC <span class="hljs-string">"Looney Tunables"</span> Local Privilege Escalation (CVE<span class="hljs-number">-2023</span> <span class="hljs-number">-4911</span>) <span class="hljs-attr">desc</span>: detect the exploitation <strong>of</strong> the CVE<span class="hljs-number">-2023</span><span class="hljs-number">-4911.</span> Attackers can inject payloads <strong>in</strong> the GLIBC_TUNABLES environment variable when running executables <strong>with</strong> the SUID permission to execute code <strong>with</strong> elevated privileges. condition: evt.type=procexit and evt.dir=> and evt.arg.sig=SIGSEGV and proc.env contains <span class="hljs-string">"GLIBC_TUNABLES=glibc."</span> <span class="hljs-attr">output</span>: Glibc exploited <strong>for</strong> privilege escalation [CVE<span class="hljs-number">-2023</span> <span class="hljs-number">-4911</span>] (evt.type=%evt.type core=%evt.arg.core status=%evt.arg.status ret=%evt.arg.ret proc.name=%proc.name cmdline=%proc.cmdline pname=%proc.pname parent_cmdline=%proc.pcmdline proc.exepath=%proc.exepath gparent=%proc.aname[<span class="hljs-number">2</span>] container.name=%container.name image=%container.image.repository container.name=%container.name container.id=%container.id user.uid=%user.uid user.loginuid=%user.loginuid user.loginname=%user.loginname) <span class="hljs-attr">tags</span>: [host, container] <span class="hljs-attr">priority</span>: WARNING </code><small><span class="shcb-language__label">Code language:</span> <span class="shcb-language__name">JavaScript</span> <span class="shcb-language__paren"> (</span><span class="shcb-language__slug">javascript</span><span class="shcb-language__paren">) </span></small>
Mitigating CVE-2023-4911
The best way to mitigate this vulnerability is through patching. However, some additional solutions do exist but will vary between vendors. If you are affected by this CVE-2023-4911, you should patch your system based on your affected distribution.
RedHat published instructions for using their SystemTap tools to detect which binaries are invoking GLIBC_TUNABLES in the environment and terminate them immediately. This solution may require the installation of additional software and repeat the process when the system is restarted.
Conclusion
The Looney Tunables vulnerability is very serious due to how many Linux distributions are involved and the relative ease of exploitation. If an attacker gains unprivileged access to a system, either through logging in as a normal user or another remote exploit, they can leverage this vulnerability to obtain root privileges. Most Linux distributions come with some form of GLIBC, so it is critical to check if you are vulnerable.
Detection can be accomplished with runtime tools using rules similar to the one provided above. Since there are currently not many ways to mitigate, patching the vulnerability should be a top priority. This vulnerability will affect not just your standard Linux server, but also containers, appliances, and IoT devices. Anywhere Linux is, this vulnerability may be present.
Related Articles:
The Evolution of DevSecOps with AI
Published: 11/22/2024
It’s Time to Split the CISO Role if We Are to Save It
Published: 11/22/2024
A Vulnerability Management Crisis: The Issues with CVE
Published: 11/21/2024
Establishing an Always-Ready State with Continuous Controls Monitoring
Published: 11/21/2024