CVE-2024-42331 - Understanding the Use-After-Free Bug in Zabbix’s Duktape Integration

On June 2024, a critical security vulnerability was disclosed in Zabbix, an enterprise-grade open source monitoring tool. This bug, CVE-2024-42331, centers on a use-after-free error due to mishandling a heap pointer between the Zabbix code and the embedded Duktape JavaScript engine.

This article is an exclusive deep dive into how this bug manifests, includes code snippets to show you what’s wrong, and walks through how an attack could exploit this vulnerability.

What’s Happening in the Code?

Within src/libs/zbxembed/browser.c, Zabbix’s es_browser_ctor function creates a “browser” object using Duktape. It keeps a pointer to the object on the heap:

/* src/libs/zbxembed/browser.c */
static duk_ret_t es_browser_ctor(duk_context *ctx) {
    ... // other code

    struct zbx_browser *browser = zbx_calloc(1, sizeof(*browser));
    duk_push_pointer(ctx, browser);
    duk_put_prop_string(ctx, -2, "\xff""ptr");
    
    ... // set up methods, finalize
    return ;
}

The pointer (browser) gets pushed and stored as a hidden property in the Duktape object (\xffptr). It is then used all throughout the object’s lifetime.

However, in src/libs/zbxembed/browser_error.c, the method browser_push_error tries to retrieve this pointer and use it:

/* src/libs/zbxembed/browser_error.c */
void browser_push_error(duk_context *ctx, ...) {
    duk_get_prop_string(ctx, , "\xff""ptr");
    struct zbx_browser *browser = duk_get_pointer(ctx, -1);
    ...
    browser->error = ...; // Vulnerable: browser pointer may not be valid
    ...
}

Here's the kicker: Duktape can run garbage collection at almost any time a JS API or allocation is performed. If the hidden pointer’s object goes out of scope (say, because no JS code references it anymore) and GC is triggered between retrieving the pointer and using it, the underlying memory could be freed. That means browser points to a freed heap area—a classic use-after-free.

JS code calls a method that triggers an error, causing browser_push_error to be called C-side.

3. Between retrieving the pointer and using it, some Duktape operation (or explicit manual triggering) gathers garbage—freeing the browser heap object.
4. The stale C pointer is accessed, leading to memory corruption or potentially remote code execution (RCE), depending on heap layout and attacker control.

Attack Scenario and Exploit Details

The attacker’s goal: trigger garbage collection at the right moment, then get Zabbix to use the freed memory.

Minimal Proof-of-Concept (PoC)

Suppose a Zabbix extension exposes JavaScript methods via Duktape to untrusted users (say, in a plugin or embedded scripting environment). Here's a simplified JS exploit:

var b = new ZabbixBrowser();
function evil() {
    b.triggerSomeError(); // this will call browser_push_error()
}
delete b; // remove all references

// Now, force garbage collection
for (var i = ; i < 100000; i++) {
    var spam = {};
}
// Depending on timing, 'b' may be GC'ed here

evil(); // use-after-free when browser_push_error accesses the invalid pointer

In reality, actual exploitation could need heap grooming or more precise timing, but in a debugging context, this could lead to a crash or dangerous reads/writes.

Real-World Weaponization

If an attacker can allocate objects into the just-freed area, they might gain arbitrary read/write abilities, potentially leading to code execution.

Why Is This Dangerous?

- Remote Code Execution: Under certain circumstances, attackers may write controlled data into the heap.

How to Fix

- Pin or Reference Count the Object: Zabbix should ensure the pointer is valid before use. For example, increase the object's reference count or use Duktape's “finalizer” mechanism to tightly couple object lifetime.
- Validate All Pointers: Never trust a pointer obtained from JS/C bindings without checking lifetime.

Duktape docs: Hidden Symbols and Heap Management
Zabbix Security Advisory: CVE-2024-42331 (pending official write-up)

Conclusion

CVE-2024-42331 highlights the dangers of mixing unmanaged C pointers with garbage-collected memory. If your project uses Zabbix or forks its Duktape integration, patch now and audit all C/Javascript integration points for similar lifetime risks.

Stay Alert

- Watch the official Zabbix GitHub for patches.

Test custom scripts for unexpected crashes or leaks.

Remember: Whenever C pointers are involved in JS or another managed language, always ask: _“Is this memory still valid?”_ before use!

- Duktape API Documentation
- Exploit Database - Use-After-Free
- CVE-2024-42331 NVD Entry *(Pending)*
- Zabbix Source: browser.c


> _If you found this write-up helpful or have questions, please leave a comment or check the provided links for more details on Duktape security and Zabbix hardening._

Timeline

Published on: 11/27/2024 12:15:21 UTC