Detect Exploitation Attempts of the Looney Tunables Vulnerability in Your System
Once again, Qualys strikes gold with a great bug!
I am talking, of course, about no other than the recently disclosed Linux vulnerability, CVE-2023-4911, also known as Looney Tunables, found in the GNU C library's dynamic loader.
In a world where genuine high-impact vulnerabilities often get lost amidst "undisclosed vulnerability in X advisories”, Qualys consistently stands out. Their latest find was yet another monumental bug, accompanied by a meticulously detailed PoC — truly a testament to their dedication.
Thanks to advisories like these, blue, red, and purple teams can excel at their roles.
The specifics of the vulnerability itself have already been covered in a number of resources with all the needed levels of details, including the original oss-security post, which is more instructive than one might expect. While it’s unnecessary to delve into the specifics in this post, I want to highlight a couple of key takeaways:
- The vulnerability lives in the GNU C Library's dynamic loader and can be leveraged with most SUID binaries.
- Although it was introduced fairly recently (April 2021), Fedora 37/38, Ubuntu 22.04/23.04 and Debian 12/13 are vulnerable.
But maybe the most interesting thing to me is the following sentence included in the oss-security post:
From the same oss-securiry post: “The dynamic loader is extremely security sensitive because its code runs with elevated privileges when a local user executes a set-user-ID program, a set-group-ID program, or a program with capabilities.”
Given that the vulnerability relies on fairly recently introduced code, I think it tells a lot about the progression margin that exists in the automatic software for such a critical piece of code that is known to have been a source of bugs in the past.
“Historically, the processing of environment variables such as LD_PRELOAD, LD_AUDIT, and LD_LIBRARY_PATH have been a fertile source of vulnerabilities in the dynamic loader.”
But the journey doesn't end at discovery. With the PoC in hand, the real test is to detect the exploitation or probing of the vulnerability.
We are assuming, based on circulating exploits and the initial advisory, that the attacker trying to exploit this vulnerability will likely crash the binary at least once before succeeding in exploiting the vulnerability. It might sound bold, but given this is a local vulnerability, there is less incentive for the attacker (unless they actually want to be stealth 😅) to have a “one-shot” exploit, given they can retry it indefinitely at little to no cost.
The initial advisory lets us think that brute-forcing addresses is implied in the exploitation method (look for the paragraph around “Where should the overwritten l_info[DT_RPATH] point to?” in the oss-security post), reinforcing the idea that crashes will be observed before successful exploitation.
We’ll be keeping an eye out for when a public exploit lands and see how things turn out. And yes, we do bet on attackers' sloppiness!
To address the exploitation threats for the Looney Tunables vulnerability, we put together two scenarios for the CrowdSec Security Engine, which can notify you when someone is attempting to exploit Looney Tunables in your system. The CVE-2023-4911 scenario offers a more targeted approach and relies on default Linx kernel logs. The auditd-suid-crash scenario offers a more generic approach and is based on auditd.
Detecting exploitation via kernel logs
Let’s first have a look at the kernel logs.
The logs tell us that the su binary (su) crashed with signal 11 (`segfault` at 7f…) in ld-linux-x86-64.so.2. It will be very specific to this vulnerability, but having your dynamic linker/loader segfaulting is bad news… I guess?
The CrowdSec scenario itself is very straightforward and doesn’t need much explanation.
The scenario is available in the CrowdSec Hub as part of the LPE collection, which can be installed using this command:
Make sure to have kernel logs in your acquisition. If you’re using pre-journalctl distribution:
Or if you are using journalctl system:
With this scenario alone, we will be able to detect attempted exploitation of the CVE-2023-4911 on any Linux machine. Isn’t that great?
Detecting exploitation via auditd logs
Crowdsec already supports auditd, and the collection includes various scenarios targeting post-exploitation behavior, so this privilege escalation should be a great addition.
For those less familiar with auditd, it is the userspace component of the Linux Auditing System and it is present on most distributions, or can be easily installed). It needs to be configured to enable logging of specific events, and if you are lost you can refer to Florian Roth’s Auditd Best Practice. It is actively maintained and covers most use cases (although quite verbose).
That being said, let’s have a look at the auditd log generated when we’re executing the PoC:
The interesting parts are:
- SYSCALL … syscall=59 … auid=1000 … euid=0: This line allows us to see that an EXECVE syscall (program execution) was done, and that the audit user ID (loginUID, auid=1000) is different from the effective user ID (euid=0). In layman's terms, it means that someone executed a suid binary, or executions via sudo.
- ANOM_ABEND … sig=11: This line means that a process crashed with signal 11, the famous SIGSEGV, segmentation fault.
With those two lines, we can detect that a SUID process was invoked, and later crashed or was terminated abnormally. While this scenario is a bit more complex than the one matching kernel logs, it has the advantage of being more generic, potentially allowing detection of exploitation attempts on any privileged binary.
The scenario looks like this:
With this scenario, we’re looking for:
- Execution of privileged (suid) binaries (evt.Meta.log_type == 'execve` …)
- Crashes (evt.Meta.log_type == 'anom_abend' …)
We’re then grouping them by PID and ensuring that it’s the same binary that is involved in both, which effectively allows us to detect a SUID binary that later crashes.
The scenario is part of the auditd collection, so it can installed like this:
And for it to work, ensure that CrowdSec is configured to read auditd logs:
With both our scenarios enabled, let’s play with the PoC again and check how our alerts look like!
On the CrowdSec side, we see our two alerts (I have both scenarios on this machine, and auditd enabled):
To make it even more useful, you can configure alert context to push the following contextual data to the CrowdSec Console:
And on the Console, our alerts with context are looking nice and clean!
As I’m finalizing this article, functional exploits are already out and seem to validate our hypothesis that brute force is the most prevalent way to exploit the Looney Tunables vulnerability. The good news is that by using CrowdSec, you are in a solid position to detect and possibly thwart such exploits.
Struggling with these scenarios? Don't fret. Hop onto our Discord and let's troubleshoot together! 😃