CVE-2021-3156 analysis.
Source: Dev.to
Background
This past week I decided to learn more about exploits and exploit analysis. I chose to investigate CVE‑2021‑3156, a sudo vulnerability from 2021 that has long since been patched. Reproducing the vulnerability presented several difficulties:
- Setting up an environment with a pre‑2021 version of sudo.
- Ensuring the binary had not been patched.
- Triggering the heap overflow (I was unable to achieve full code execution due to heap‑layout differences in Docker).
Vulnerability Details
CVE‑2021‑3156 is a heap‑based buffer overflow in sudo. The vulnerability allows writing data beyond the bounds of an allocated buffer, corrupting adjacent memory on the heap.
The exploit targets the service_user struct in glibc’s Name Service Switch (NSS) system, which contains function pointers used for user and group lookups. By overflowing the buffer, an attacker can overwrite these function pointers and redirect them to attacker‑controlled code.
When sudo calls an NSS function (e.g., getpwnam_r() to look up user information), it follows the corrupted function pointer and executes the attacker’s code. Because sudo runs with root privileges, the injected code inherits those privileges, allowing the attacker to spawn a root shell.
Exploit Setup
-
Initial attempt with a virtual machine – I tried running Ubuntu 18.04 in the UTM virtualization application. The older Ubuntu image proved problematic: installation repeatedly crashed, and even the live image would not run. I abandoned this approach.
-
Docker container – I switched to a Docker container based on Ubuntu 18.04, which ran successfully on my machine. However, when I attempted the exploit, sudo reported a usage error, indicating that the binary had been updated. Checking the binary’s timestamp showed it was compiled in 2023—two years after the patch.
-
Installing the vulnerable sudo – I downloaded the old version of sudo inside the Docker instance, installed it, and ran it from its location. This allowed me to trigger a memory‑access error with the vulnerable sudo binary.
Attempted Exploitation
I downloaded the public exploit scripts and tried to gain root access. The scripts assume the default sudo binary location, so they failed repeatedly. By creating a symlink to the newly installed sudo, the heap‑overflow attempt could be executed, but I could not achieve root access.
After experimenting with multiple chunk sizes, the exploit still did not succeed. I suspect that Docker arranges heap memory substantially differently from a typical Ubuntu installation, making the exploit more difficult to achieve in this environment.