Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2023-4911 — CVE-2023-4911 (Looney Tunables) analysis report and Docker reproduction lab | Kitploit
Tools/GitHubGitHub/baeseungwon1010/cve-2023-4911
Privilege EscalationVulnerability AnalysisExploitationLearning & EducationBinary ExploitationLabs & Practice
GitHubbaeseungwon1010/cve-2023-4911

CVE-2023-4911

CVE-2023-4911 (Looney Tunables) analysis report and Docker reproduction lab

View Repository
452 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

glibc Heap Buffer Overflow Vulnerability (CVE-2023-4911)

ItemDescription
CVE IDCVE-2023-4911
Attack TypeHeap Buffer Overflow → Local Privilege Escalation
CVSS 3.17.8 (High)
Disclosure Date2023-10-03
Vulnerability Pointglibc dynamic loader (ld.so) GLIBC_TUNABLES parser
Affected Versionsglibc 2.34 ~ 2.38

1. Overview

CVE-2023-4911 is a heap buffer overflow vulnerability that occurs when the dynamic loader of the GNU C Library (glibc) parses the GLIBC_TUNABLES environment variable. By exploiting this overflow, an attacker can manipulate the dynamic loader's library search path (RPATH). When a SUID root binary (su, sudo, etc.) is executed, the attacker can force the loader to load a malicious shared library instead of the legitimate one, thereby executing arbitrary code with root privileges. Since glibc is a core component of virtually all major Linux distributions, this vulnerability affected most glibc-based distributions released after April 2021.

2. Vulnerable Code Snippet

while (true)
{
    char *name = p;
    size_t len = 0;

    /* Find the length of the name */
    while (p[len] != '=' && p[len] != ':' && p[len] != '\0')
        len++;

    /* If it ends without '=', terminate */
    if (p[len] == '\0')
    {
        if (__libc_enable_secure)
            tunestr[off] = '\0';
        return;
    }

    /* If ':' is encountered first, it's an invalid entry */
    if (p[len] == ':')
    {
        p += len + 1;
        continue;
    }

    /* Met '=', move to start of value */
    p += len + 1;

    /* Calculate value from original string */
    char *value = &valstring[p - tunestr];

    len = 0;

    /* Find length of value */
    while (p[len] != ':' && p[len] != '\0')
        len++;

    ...
    /* Copy to tunestr */
    ...

    if (p[len] != '\0')
        p += len + 1;
}

3. Root Cause Analysis

3.1 Normal Processing Flow

  1. __tunables_init() finds GLIBC_TUNABLES in the environment variable list.
  2. tunables_strdup() allocates a buffer using __minimal_malloc() and copies the original string (at this point, malloc is a very early implementation that has not yet been fully initialized).
  3. parse_tunables() iterates through this buffer using : (colon) as a delimiter, splitting each key=value pair and assigning the value to the corresponding tunable.

3.2 Vulnerability Point

parse_tunables() processes a single tunable in the order: name parsing → moving p → value parsing → moving p. Under normal input, after processing the value, p moves to the start of the next tunable to parse the next entry.

However, when given an input of the form name=name=value, for example:

GLIBC_TUNABLES=glibc.malloc.mxfast=glibc.malloc.mxfast=AAAA...(long string)

During the first parsing, the entire glibc.malloc.mxfast=AAAA... is recognized as a single value and copied into the tunestr buffer. Since there is no colon (:) after the value to separate the next tunable, the parsing pointer (p) does not move to the next entry but instead points back to the beginning of the already copied value.

The problem is that this value itself has a name=value format. In the next iteration, the parser incorrectly treats it as a new tunable and writes duplicate data into the buffer. Since tunestr was allocated only for the size of the original string, the duplicate writes cause a heap buffer overflow.

3.3 Effects of the Overflow

The heap buffer overflow overwrites adjacent heap areas allocated consecutively by __minimal_malloc(). An attacker can use this to modify the pointer to l_info[DT_RPATH] in the link_map internal structure of the dynamic linker (ld.so) to point to a stack address controlled by the attacker.

In that stack area, a pre-manipulated Elf64_Dyn structure is placed, which specifies a directory of the attacker's choice as the new library search path (RPATH). As a result, ld.so loads the attacker's malicious shared library instead of the legitimate system library.

4. Attack Chain

  1. The attacker constructs a GLIBC_TUNABLES environment variable of the form name=name=value.
  2. The attacker executes a SUID program (e.g., su) with normal user privileges.
  3. The kernel, due to the SUID bit, changes the process's effective UID to root and then executes the dynamic linker (ld.so).
  4. A heap buffer overflow occurs in parse_tunables() of ld.so.
  5. Using the overflow, the attacker manipulates the l_info[DT_RPATH] pointer in link_map to point to a stack address containing a fake Elf64_Dyn structure.
  6. ld.so uses the manipulated RPATH information to load a malicious libc.so.6 prepared by the attacker.
  7. The initialization code (or modified startup routine) of the malicious libc.so.6 executes with root privileges, performing setuid(0), setgid(0), and executing /bin/sh.
  8. This process takes place before the authentication logic of su runs, thus obtaining a root shell without password verification.

The PoC uses a brute-force approach that repeatedly calls execve() until the desired memory layout is achieved under the influence of ASLR. Therefore, the success and time required may vary depending on the environment; typically hundreds to thousands of attempts are needed.

5. Reproduction Conditions

  • Presence of binaries that can be used for privilege escalation (e.g., SUID, SGID).
  • The attacker must be able to execute the binary with arbitrary environment variables.
  • glibc must be an unpatched version.

6. Practice Environment Reproduction (PoC)

First, clone the contents from the git repository to a directory.

git clone https://github.com/baeseungwon1010/CVE-2023-4911

Build the Docker image using the following command:

cd C* && docker compose run --rm cve-2023-4911-lab

After entering the container, run the exploit code:

cd /home/student/exploit && ./exp

After running and waiting, you can see that the user changes from a normal user to sudo(0).

7. Mitigation

Update glibc from the vulnerable version to a patched version. After patching, if possible, reboot or restart to ensure no previous version of glibc remains in memory. If immediate patching is not possible, a temporary workaround is to remove unnecessary SUID, SGID, and similar processes.

8. References

  • NVD: CVE-2023-4911
  • Ubuntu Security Notice: CVE-2023-4911
  • leesh3288/CVE-2023-4911 PoC
  • Debian Sources - glibc 2.28-10 dl-tunables.c
Download Tool