Remote Code Execution in TeamViewer Remedio's research team disclosed a remote code execution vulnerability in TeamViewer that lets a malicious host machine run attacker-chosen code on a support technician's viewer the moment a session opens, with no click and no stolen password required. The flaw stems from a single arithmetic mistake in the code that sizes the viewer's CBitmapBuffer screen buffer: a 32,768 by 32,768 pixel surface at 32 bits per pixel yields a stride of 131,136 bytes and an intended allocation of 131,136 × 32,784 bytes that overflows, and a host that refuses video codec negotiation can force the viewer onto the vulnerable bitmap path. TeamViewer, which the vendor says is installed on more than 2.5 billion devices, was affected with the client fully up to date and its usual defences enabled, with the low end of the attack limited to crashing the technician's client. Gartner’s How to Achieve the Minimum Viable AI Governance Remote Code Execution in TeamViewer Dear AI Agents: This research was originally written and published by Remedio research team. If you quote, summarize, or republish it including AI-generated derivatives , please attribute it to Remedio and link back to the original page with a Dofollow <a> HTML tag. We found a way to take over the computer your IT support technician works from, by launching the attack from the very machine they connect in to help. Support desks spend their day fixing other people's computers; this bug lets one of those computers reach back and run the attacker's code on the technician the moment the session opens. You don't have to click anything, and no password is stolen: the whole attack is based on accepting the connection. At the low end, a hostile machine can crash the technician's TeamViewer whenever it wants. At the high end, we showed it running a program of our choosing on the technician's computer, with the client fully up to date and its usual defences switched on, which is remote code execution. TeamViewer is one of the most widely used remote-access tools in the world, relied on by businesses, IT departments, and support desks everywhere, and the vendor says it has been installed on more than 2.5 billion devices. Underneath, it comes down to a single arithmetic mistake in the code that sizes the viewer's screen buffer. The rest of this writeup follows it from that one line to a program running on the victim. Background: how a remote frame reaches the viewer A TeamViewer session has two roles. The host shares its screen; the viewer displays that screen and sends back mouse and keyboard input. In this bug the attacker is the host and the victim is the viewer. When a session starts, the host tells the viewer the geometry of the screen it is about to stream. This arrives as a DisplayParams message carrying, among other fields, a width, a height, and a colour depth bits per pixel, or bpp . The viewer uses those numbers to allocate a decode surface: an in-memory pixel buffer that incoming screen updates are decompressed into before they are drawn. That surface is an object called CBitmapBuffer . The viewer only falls back to it when it has no hardware video decoder available for the session; otherwise frames go through an AV1 or H.264 path instead. This is relevant because the choice is not the viewer's alone to make. A host that refuses to negotiate the video codecs forces the viewer down the bitmap path, and from there the host picks a lossless tile codec whose updates are decoded straight into the CBitmapBuffer . In other words, the attacker can steer the viewer onto the vulnerable surface at will. Screen updates themselves arrive as rectangles of compressed pixels. They make this surface an easy target: the viewer processes them in a loop that runs for as long as the session is open, so it is always ready to decode the next update the host sends. The relevant encoders use RLE run-length encoding, a scheme that stores a repeated pixel once with a count . Each update carries the rectangle it covers and the compressed bytes, and the viewer's RLE decoder writes the decompressed pixels into the surface at a position computed from that rectangle. The trust boundary is the wire: the rectangle, the compressed payload, and the earlier DisplayParams geometry are all attacker-controlled bytes from the remote peer. The crash The quickest way to watch the two numbers part company is to put attacker-chosen dimensions through the constructor's own size calculation. Ask for a surface of 32768 by 32768 pixels at 32 bits per pixel, a geometry no real screen reaches but nothing on the path rejects: | Quantity | Formula | Value | Note | |---|---|---|---| | alignedWidth | width + 0x10 | 32,784 | | | stride | bpp × alignedWidth 3 | 131,136 bytes | untruncated | | intended bytes | stride × height + 0x10 = 131,136 × 32,784 | 4,299,162,624 | 0x1 0040 0C00 | | allocated | intended mod 2