A critical security flaw was discovered in the open-source drachtio-server, specifically in version .8.18. Assigned CVE-2022-45474, this vulnerability exposes the server to a use-after-free bug in the request-handler.cpp file, particularly within the event_cb function triggered for any incoming request. This issue has a serious impact as it can be exploited to achieve remote code execution or cause the server to crash.
In this post, I’ll break down what happened, explain how the vulnerability works, share a code snippet showing the bug, provide links to original references, and describe how an attack could be executed in real-world conditions.
What is A Use-After-Free?
A use-after-free bug happens when software tries to use or access memory _after_ it’s already been freed (released) back to the system. If an attacker manages to exploit such a bug, they may be able to execute arbitrary code, crash the server, or possibly bypass security checks.
Drachtio-server, a SIP (Session Initiation Protocol) application server, is used in signaling for VoIP and messaging. Like a lot of network servers, robustness and security are crucial.
Vulnerable File and Function
src/request-handler.cpp
Look for the event_cb function, which is supposed to handle incoming SIP requests.
What’s the Bug?
After a request is processed and its corresponding memory is freed, the function doesn’t stop referring to the freed memory. This means that under certain situations, another part of the code could _re-use_ that same chunk of memory for something else, leading to unpredictable behavior.
Code Snippet: Reconstructing the Vulnerability
Here’s a simplified and _representative_ excerpt; names are from the original drachtio-server request-handler.cpp (GitHub):
void request_handler::event_cb(msg_t* msg, int ev) {
//...
msg_t* request = get_request_from_msg(msg);
// Process request
process_request(request);
// Free the request
delete request;
// Incorrect: Still referencing 'request' after freeing it!
log("Request handled: %s", request->summary()); // Use-after-free!
}
Here, the program frees request (with delete request), but then still tries to use it in request->summary(). If an attacker can trigger code paths that hit this bug, it could result in reading invalid memory or, in the worst case, running arbitrary code chosen by the attacker.
Official References
- NVD entry for CVE-2022-45474
- drachtio-server GitHub repo
- drachtio-server release history
Force Use-After-Free
The input or sequence of inputs is crafted in such a way that the server’s event_cb function will free a request and then access it again.
Hijack Freed Memory
If the server allocates new memory between the free and the use, the attacker could control what sits at that memory location.
Leverage for Code Execution
If the attacker is able to get server code to jump through a pointer or read attacker-controlled data, this could crash the server or potentially allow arbitrary code execution.
Real-World Example
Suppose an attacker floods your server with SIP requests designed to get the server to process, free, and then still reference the freed memory. By carefully timing these messages and knowing the internals of the drachtio-server, an advanced attacker could use this to take control of the server or cause repeated crashes (denial of service).
Sample Proof-of-Concept (PoC)
While responsible disclosure discourages supplying a working exploit, here’s a rough proof-of-concept approach _description_:
manipulate SIP header fields so that the memory layout is predictable.
3. After freeing, immediately send another request so the server allocates new data at the recently-freed address.
4. Observe if the server returns data from previously-sent requests or starts misbehaving/crashing.
Patch and Mitigation
Patched Version:
Upgrade to any drachtio-server release _after_ .8.18 where this bug has been fixed (ideally, check latest releases for details).
Manual Patch:
Here’s a fixed version of the code snippet
void request_handler::event_cb(msg_t* msg, int ev) {
//...
msg_t* request = get_request_from_msg(msg);
// Process request
process_request(request);
// Log before deleting!
log("Request handled: %s", request->summary());
// Free the request
delete request;
// Now, no more references to 'request'
}
Or, even safer, set pointers to nullptr after freeing them
delete request;
request = nullptr;
Final Thoughts
This vulnerability shows why memory management bugs like use-after-free are so dangerous in C++ network servers. If you’re running an affected version of drachtio-server, update ASAP to stay secure.
Useful Links
- CVE-2022-45474 – NVD
- Draft of Patch / Changelog
- Understanding Use-After-Free
Have questions about this bug, or found it in your deployment? Let the community know! Stay safe!
*Written exclusively for this post: please link back if you found it useful.*
Timeline
Published on: 11/18/2022 18:15:00 UTC
Last modified on: 11/28/2022 22:12:00 UTC