This repository contains the exploit proof of concept of a vulnerability in TeamViewer that enables an unprivileged user to load an arbitrary Kernel Driver into the system. I would like to thank Zero Day Initiative for the coordination with them to report and responsibly disclose the vulnerability.
- https://www.cve.org/CVERecord?id=CVE-2024-7479
- https://www.cve.org/CVERecord?id=CVE-2024-7481
- https://www.zerodayinitiative.com/advisories/ZDI-24-1289/
- https://www.zerodayinitiative.com/advisories/ZDI-24-1290/
- https://www.teamviewer.com/en/resources/trust-center/security-bulletins/tv-2024-1006/
The details about the research that ended with these vulnerabilities can be found in the following three-part blog series on my blog. They cover these vulns in more detail and also show where I failed during the process. Part three is the fun one :P.
- https://pgj11.com/posts/Finding-TeamViewer-0days-Part-1/
- https://pgj11.com/posts/Finding-TeamViewer-0days-Part-2/
- https://pgj11.com/posts/Finding-TeamViewer-0days-Part-3/
Videos of the exploit can be found here:
After being able to spoof (just some simple authentication as detailed in the blog) a valid TeamViewer client when connecting to the SYSTEM service IPC it was possible to trigger an arbitrary driver installation. TeamViewer was not verifying the signature of the driver being installed.
Thus a privilege scalation USER to KERNEL was possible thanks to TeamViewer.
One of the best approaches is to use the well-known technique BYOD, Bring Your Own Vulnerable Driver to load a valid signed driver into Windows Kernel and then exploit it in order to perform privileged actions from user level, like changing the token of an arbitrary process with a privileged one.
When TeamViewer is installed on the system, it creates a service that runs as SYSTEM, TeamViewer_service.exe
This service is a helper for the client to some tasks. Thus, the client does not run with elevated privileges and some tasks are delegated to the service.
The communication with the service (IPC) is implemented through sockets (using Overlapped I/O and IoCompletionPort). By default, TeamViewer SYSTEM services listens on 5939/tcp at localhost.
TeamViewer is not filtering the parameter sent by the client to ask for the driver installation nor signature check, etc.
So the idea is: we will spoof a TV client an asks for a VPN Driver installation but indicating another INF. I reutilized the same original INF of TeamViewer but in another (non-privileged) path renaming the "bad" driver to teamviewervpn.sys, as this is the driver name being targetted by the original INF.
This bypasses also TeamViewer option Changes require administrative rights on this computer.
This check is only effective via the GUI, as TeamViewer options is disabled when clicking the button with an unprivileged user. But it is possible to connect to the socket and perform the arbitrary driver load.
The exploit is version dependant because of the IPC message where the client specified its PID and another data among the version. The version of the client must match the version of the SYSTEM service. The exploit must be modified (lines 140 to 143) in Main.cpp to the TeamViewer_service.exe version that is being targeted.
So, basically, we spoof a TeamViewer client connecting the SYSTEM service and request the installation of an arbitrary driver. TeamViewer service kindly load it into the Kernel.
TeamViewer has another IPC message very similar to the first one that I discovered first (thrown when clicking Install VPN Driver). This other message is to install the Printer Driver.
So, essentially, CVE-2024-7479 and CVE-2024-7481 are the same but TeamViewer committed the same error two times. The message are, although different, very similar. They have different IPC Method Id.
The results is the same, an arbitrary driver can be loaded.