Full Report
Apache Guacamole is a remote Desktop gateway used for accessing hosts and isolated applications from the webs browser. The application itself contains a client facing server written in Java and a local server that the client server interacts with written in C. The server makes heavy use of parallelism to make it fast. There are 8+ threads that do various things, from handling a connection to communications back to the client and much more. Since there were so many different threads running, they were curious about the security of this. In general, mutexes were used and threads were loosely coupled, making it mostly secure. From a developers perspective, reasoning about multithreaded code is very hard to do, meaning that there are likely bugs in this area. Staring at the audio processing seems to be a fruitful area because there were three threads involved with it. One thread (the user thread) creates two buffers: one for the user and one for the socket connection, with the user structure having a pointer to the socket. After this, a third thread, called the rdp_client_thread, is created for a RDP connection. This structure holds a pointer to the user structure, creating a pointer chain. These different objects can be closed or destroyed at any point. By disconnecting from a session (after using the microphone), the user_thread is torn down - this frees the socket and user structures. However, the rdp_client_thread still has a pointer to this object! So, if a message is sent to close the audio channel, this is accessing a freed pointer! This creates a classic use after free vulnerability. To exploit this, the author looked into overlaying this object over the top of something else. However, the thread was closed quickly afterwards, making this approach not very helpful. So, we'll have to dive into threads and glibc malloc clean up to make this work! There is a function pointer at slot 8 in the user object to another poitner. So, if we could edit this and call it from the other thread, it would be game over. By abusing some functionality within glibc's freeing process, it was possible to stick the freed user chunk into the unsorted bin, which references some data controlled by the attacker. Although we don't have a memory leak, the pointer to a function pointer now goes from our freed data, to free data that we control (since it's never cleaned up in malloc). To get control over the execution, an attacker can call strdup() with a size of 0x90. But, this is limited to zero nullbytes, making it infeasible. So, now what? malloc is limited to a small amount of arenas or heaps. By sharing connections on Apache Guacamole, we can create lots of arenas, until we hit the limit. This means that we can use the UAF on a different thread that is much more useful! The author found that getting the input_thread allocated with arena4 was the best thing for controlling the data within for our UAF. With control over RIP on the function pointer, we need to setup a ROP chain. The lock_handler() function pointer is called on an argument provided by itself. Since the data after the function pointer gets corrupted, they use a pivot gadget before proceeding. Once done, they called system with their provided parameter to pop a shell. Pretty neat! Being a big fan boy of malloc heap exploitation, I really enjoyed this article! The knowledge required to exploit this was super high, which was cool to see. I found the simplicity of the UAF interesting as well - just a simple dangling pointer with no race conditions. Amazing post! :)
Analysis Summary
# Vulnerability: Use-After-Free in Apache Guacamole Audio Input Handling
## CVE Details
- **CVE ID**: CVE-2023-30576 (Note: Article references the series' previous CVE-2023-30575; however, this specific UAF is tracked as 30576)
- **CVSS Score**: 8.1 (High)
- **CWE**: CWE-416 (Use-After-Free)
## Affected Systems
- **Products**: Apache Guacamole (guacd)
- **Versions**: Versions prior to 1.5.2
- **Configurations**: Systems with the RDP "audio input feature" (microphone redirection) enabled.
## Vulnerability Description
The vulnerability arises from a concurrency issue involving three threads: `input_thread`, `user_thread`, and `rdp_client_thread`. When a user disconnects from a session after using the microphone, the `user_thread` is torn down, freeing the memory associated with the **socket** and **user** structures.
However, the `rdp_client_thread` maintains a pointer chain (Audio Buffer -> User -> Socket). If a message is received to close the audio channel after the user has disconnected, the `rdp_client_thread` attempts to access the socket's `lock_handler` function pointer via the freed `user` object. This creates a Use-After-Free (UAF) condition where a dangling pointer is dereferenced.
## Exploitation
- **Status**: PoC described / Functional exploit developed by researchers.
- **Complexity**: High (Requires deep knowledge of glibc heap internals, arena exhaustion, and ROP chain construction).
- **Attack Vector**: Network (Remote).
- **Technical Details**:
- **Arena Exhaustion**: To bypass glibc's thread-local heap (arenas) and ensure the freed memory can be manipulated by other threads, the attacker creates many connections to hit the internal arena limit.
- **Heap Spraying**: The attacker uses a `strdup()` primitive (size 0x90) to overlay controlled data on the freed `user` chunk.
- **Control Flow Hijack**: By manipulating the `lock_handler` function pointer and using a `leave;ret` pivot gadget, the attacker redirects execution to a ROP chain that calls `system()` with an attacker-supplied command.
## Impact
- **Confidentiality**: High (Code execution allows credential harvesting and spying on all active sessions).
- **Integrity**: High (Full control over the Guacamole server).
- **Availability**: High (Ability to crash the gateway or take over its processes).
## Remediation
### Patches
- **Apache Guacamole 1.5.2**: This version includes a comprehensive patch to address the concurrency and memory management issues. Users should upgrade immediately.
### Workarounds
- Disable "Audio Input" (microphone redirection) in RDP connection settings if patching is not immediately possible.
## Detection
- **Indicators of Compromise**: Monitor for unusual spikes in the number of connection attempts/threads (indicative of arena exhaustion attempts). Look for unexpected child process executions (`sh`, `system`) originating from the `guacd` process.
- **Detection Methods**: Use memory-safe allocators or tools like AddressSanitizer (ASan) in testing environments to identify dangling pointers.
## References
- **Vendor Advisory**: [https://guacamole.apache.org/support/#security-advisories]
- **Original Research**: [https://www.sonarsource.com/blog/parallel-code-security-the-challenge-of-concurrency/]
- **Supportive Research**: [https://research.checkpoint.com/2020/apache-guacamole-rce/]