【漏洞预警】TeamViewer RCE 漏洞可致恶意主机接管,25亿设备告急
原创
骨哥说事
骨哥说事
骨哥说事
2026年10月31日 11:06
上海
去阅读
| *声明:*文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。 |
防走失:https://gugesay.com/
不想错过任何消息?设置星标↓ ↓ ↓
演示视频说明:左侧的IT支持人员计算机通过正常的TeamViewer会话连接到右侧的恶意主机。视频随后完整演示了攻击者如何通过该会话完全接管IT支持人员的计算机。
我们发现的漏洞提供了一种极为危险的攻击方式:攻击者可以从IT支持人员连接提供帮助的计算机上,反过来完全控制支持人员自己的工作计算机。想象一下,技术支持团队整天忙于修复其他人的计算机漏洞,然而本应被修复的计算机却能反过来在会话建立的瞬间,在IT人员的计算机上执行攻击者指定的恶意代码。整个攻击过程无需受害者点击任何额外内容,也不需要窃取任何密码——攻击仅仅利用了正常接受远程协助连接这一标准操作流程。
漏洞严重性等级分析
最低威胁级别:恶意主机可以随时恶意崩溃IT支持人员的TeamViewer客户端,造成服务不可用最高威胁级别:我们成功验证攻击者可以在完全更新且防御机制正常启用的TeamViewer客户端上,直接执行任意代码,实现完整的远程代码执行(RCE)
TeamViewer作为全球使用最广泛的远程桌面工具之一,被企业、IT部门和技术支持团队普遍依赖。官方统计显示,该软件已在超过25亿台设备中安装部署,其安全性直接影响全球企业和个人的数字基础设施安全。
漏洞核心根源:看似复杂的攻击链,本质上源于一行代码中的简单整数溢出错误。本文将从这行基础代码出发,完整追踪攻击链如何从初始的算术溢出逐步发展到最终的远程代码执行。
攻击向量示意图:IT技术人员常规连接远程主机提供技术支持;然而远程主机却通过同一会话发送精心构造的陷阱屏幕帧,从而在技术人员计算机上执行攻击者指定的恶意代码。
技术背景:TeamViewer屏幕渲染机制解析
在标准TeamViewer会话中存在两个明确的角色:
- 主机端(Host):负责共享自己的屏幕显示内容
- 查看端(Viewer):负责显示主机画面并向主机发送鼠标键盘输入
在这个特定漏洞中,攻击者扮演主机角色,受害者则是查看端用户。当会话建立时,主机通过\\DisplayParams协议消息\\告知查看端即将传输的屏幕参数信息,包括:
- 屏幕宽度(width)
- 屏幕高度(height)
- 色彩深度(bpp,单位:比特每像素)
查看端使用这些参数在内存中分配一个像素缓冲区(称为解码表面decoding surface),所有后续从主机接收的屏幕更新都会先解压到此缓冲区再进行实际绘制显示。
核心漏洞组件:CBitmapBuffer对象
TeamViewer使用名为\\CBitmapBuffer的对象来管理这个像素缓冲区。在通常情况下,只有当查看端没有可用的硬件视频解码器时才会使用该对象;否则屏幕帧会通过AV1或H.264视频编解码路径\\进行处理。
关键发现:使用CBitmapBuffer的决策不完全由查看端控制!主机可以通过故意拒绝协商视频编解码选项,强制将会话导向脆弱的位图处理路径。在这种模式下,主机会选择一种无损瓦片编解码器,其输出直接解码到CBitmapBuffer中。这意味着攻击者完全可以主动选择并进入这个包含漏洞的处理路径!
攻击面扩大:屏幕更新处理循环
屏幕更新以矩形压缩像素区块的形式从主机传输到查看端。这使得CBitmapBuffer成为极为理想的攻击目标,因为查看端会在整个会话期间持续运行处理循环,随时准备解码主机发送的下一个更新区块。
具体编码机制是RLE游程编码(一种将重复像素存储一次的压缩算法)。每个更新区块都包含:
- 矩形覆盖范围信息(起始坐标和尺寸)
- 压缩后的像素数据
- 查看端的RLE解码器会根据矩形位置计算写入位置,将解压后的像素写入缓冲区
完全失控的信任边界:协议层所有数据要素都直接受攻击者控制:
- 矩形坐标和尺寸参数
- 压缩后的像素数据
- 初始的
DisplayParams几何参数
触发崩溃:整数溢出的实际效果
理解攻击原理的最直观方式是观察攻击者精心设计的屏幕尺寸参数如何通过构造函数的大小计算逻辑。以不真实的巨大屏幕尺寸为例:32768×32768像素,32位色彩深度(正常屏幕不可能达到此分辨率,但协议层没有任何限制机制):
| 参数项 | 计算公式 | 实际值 | 关键说明 |
|---|---|---|---|
| 对齐宽度(alignedWidth) | width + 0x10 | 32,784 | |
| 行跨度(stride) | (bpp × alignedWidth) >> 3 | 131,136字节 | 未截断 的原始值 |
| 理论所需字节数 | stride × (height + 0x10) = 131,136 × 32,784 | 4,299,162,624字节 | 0x1\_0040\_0C00 (约4GB) |
| 实际分配字节数 | 理论值 mod 2^32(32位取模) | 4,195,328字节(~4MB) | 0x0040\_0C00 (整数溢出!) |
| 声称行数/实际容纳行数 | (height + 0x10) vs. 分配大小 ÷ stride | 32,784行 / 约31行 | 从第32行开始全部越界! |
DisplayParams参数设定:width = height = 0x8000 (32,768), bpp = 32
图1. 构造函数中攻击者控制维度导致的致命算术错误。理论所需大小溢出32位整数范围,导致operator new[]实际只分配了约4MB缓冲区,但整个系统仍错误地认为自己拥有32,784行的存储空间。
向这个严重尺寸不足的缓冲区写入任何覆盖整个声明尺寸的屏幕更新时,解码器会尝试将完整的\"屏幕内容\"写入实际仅能容纳31行的缓冲区!在标准Windows版TeamViewer上,这会导致稳定、可重复的远程拒绝服务崩溃。
更危险的是,这种写入不会在缓冲区边界处优雅停止。它会完全越过缓冲区末端,继续侵入堆内存中的后续分配区域。这不是简单的off-by-one边界错误,而是完全可控的堆缓冲区溢出,攻击者可以决定溢出数据的具体内容和覆盖范围!
漏洞根源函数分析
CBitmapBuffer构造函数中的关键代码问题可以简化为以下几个核心步骤:
// 所有参数(width, height, bpp_bits)均来源于未经验证的远程DisplayParams消息
// 计算行跨度,存储在plane+0x20位置(注意:此处参数未经截断!)
stride = (bpp_bits * (width + 0x10)) >> 3;
// 致命错误:32位乘法!结果在模2^32后可能发生整数溢出
plane.byteSize = (uint32)(stride * (height + 0x10));
// 实际分配基于溢出后的错误大小
buf = operator_new(stride * (height + 0x10)) );
图2. 关键在于stride * (height + 0x10)的乘法仅使用32位算术计算,然后才将结果扩展到64位用于内存分配。这种运算方式完全忽略了整数溢出的可能性,导致内存分配的缓冲区远比计算表面所需的小得多,而系统其他部分仍在继续使用未截断的原始尺寸参数。
边界检查为何完全失效?
理论上,如果解码器在每次写入时都验证实际分配的缓冲区大小,完全可以避免此类问题。但实际代码却进行了完全错误的验证逻辑:
if ((D_height < y2) || (D_width < x2))
return \"invalid rectangle\"; // 矩形无效,拒绝处理
// D_width和D_height引用的是声明的表面尺寸(未截断!)
// 实际写入地址计算:base + y*stride + (x*bpp >> 3)
图3. 边界检查仅仅验证写入矩形是否在声明的表面尺寸范围内,因此一个覆盖完整表面的矩形(0, 0, 32768, 32768)会顺利通过检查。写入地址基于base + y*stride计算,而实际分配仅覆盖约31行,意味着从第32行开始的所有写入都完全越界!检查逻辑从未与真实分配的大小进行比对,因此完全无法检测到整数溢出问题。
这才是漏洞的完整本质:内存分配操作依据的是整数溢出后的错误大小,而边界检查和后续的写入操作依据的却是原始的、未截断的尺寸参数。攻击者精心构造的维度参数使这两个数字相差近2^32倍——分配的内存急剧缩小,但写入权限依然保持原有范围。
攻击路径可达性分析
我们首先要确认的是攻击者是否能完全控制所有关键参数。通过逆向分析TeamViewer客户端的接收处理路径,我们发现网络协议层和解析逻辑都没有对屏幕尺寸参数施加任何合理限制。这意味着恶意主机可以完全自由地构造任意大小的屏幕参数,这些参数会原封不动地传递到易受攻击的构造函数逻辑中。
这在实际攻击场景中意义重大:恶意或被入侵的主机可以在完全正常的、已建立的TeamViewer会话中,使用标准协议支持的消息格式触发此漏洞。我们在实验室环境中成功验证了完整的攻击传递路径,确认实际攻击场景中的传递机制完全可行。
漏洞触发的高级控制
让目标客户端崩溃只是攻击的最基础效果。真正危险的是攻击者可以精确控制溢出缓冲区的大小和布局。由于分配大小计算公式为(stride * (height + 16)) mod 2^32,攻击者可以通过巧妙选择维度参数,使缓冲区几乎达到任意预期的大小,同时写入操作仍然会尝试覆盖将近2^32字节的虚假范围。
两个关键攻击场景
- 大规模溢出攻击:使用32768×32768的大尺寸参数,创建一个数兆字节的缓冲区,溢出操作会在整个堆内存中大面积涂抹,破坏大量堆结构。
- 精确溢出攻击:使用特殊维度参数(
Width = 0xFFFFFFF5, Height = 1, BPP = 8),溢出后缓冲区仅有约0x440字节,落入特定的堆大小类别中,紧邻可以进行\"堆布局装饰(heap grooming)\"的其他对象。
这意味着攻击者拥有的不仅仅是简单的拒绝服务能力,而是:
- 完全可控的堆缓冲区溢出原语
- 可精确指定溢出内容
- 可精准控制溢出后的目标堆大小类别
- 线性的大范围内存覆盖能力
从内存破坏到完整代码执行
在堆缓冲区溢出的基础上实现可靠、通用的远程代码执行(RCE) 才是真正的技术挑战。事实证明,我们成功绕过了Windows所有现代安全机制,实现了完整的攻击链:
- 内存损坏目标:被覆盖的
CBitmapBuffer对象是活动对象,查看端后续会通过其第一个字段中的虚函数指针进行调用 - 控制流劫持:通过溢出覆盖该指针,完全重定向控制流
- 安全机制绕过:
- Control Flow Guard(CFG):现代Windows的核心控制流完整性保护
- DEP(数据执行保护):防止从数据区域执行代码
- ASLR(地址空间布局随机化):内存地址随机化防御
- 最终执行:我们成功将控制流重定向到
WinExec系统API,从而在受害者计算机上执行任意攻击者指定的代码
完整的端到端攻击链在我们的演示环境中完全实现,所有的攻击步骤都运行在标准的、官方发布的TeamViewer二进制文件上,充分证明攻击的实际可行性。
漏洞影响范围和受影响版本
此漏洞在默认配置下完全可及,仅需要一个正常的远程协助会话接受操作即可触发。TeamViewer产品安全团队正式将此漏洞评为CVSS 3.1评分8.8分(高风险),攻击向量为AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H,其中UI:R表示需要用户接受远程会话连接。
表:受影响版本清单
| 平台 | 组件 | 测试版本 | 漏洞状态 |
|---|---|---|---|
| Windows | TeamViewer.exe (查看端) |
15.80.6.0 | 确认受影响 |
| Windows | TeamViewer_Desktop.exe (主机端) |
15.80.6.0 | 确认受影响(可实施攻击) |
| Windows | TeamViewer.exe (查看端) |
15.82.6.0 | 易受攻击的构造函数仍存在(已观察验证) |
| 全平台 | 修复版本 | 15.83 | 已修复 |
负责任的漏洞披露时间线
- 2026年8月14日:向TeamViewer产品安全团队正式提交漏洞报告
- 2026年10月22日:TeamViewer产品安全团队接受漏洞报告,确认为高风险(CVSS 8.8);分配漏洞编号CVE-2026-111585
- 2026年10月27日:发布修复版本TeamViewer 15.83,彻底修复漏洞;详细安全公告见TV-2026-1011
我们衷心感谢TeamViewer产品安全团队在本次漏洞处理过程中展现的专业态度和高效响应。他们在确认漏洞后迅速开发并发布了修复版本,展现了维护产品安全的坚定决心,保障了全球超过25亿用户的数字安全。
安全研究和漏洞披露:Omri Dar,Remedio安全研究团队。
深度安全反思与行业启示
漏洞的核心本质仅仅是一个32位整数乘法操作。正是这个看似简单的算术错误,将一个普通的屏幕渲染功能转变成了完整的远程代码执行攻击链。根本原因在于:整个写入处理路径中,没有任何环节将实际写入范围与真实分配的内存大小进行比对验证。
这种漏洞模式具有普遍性的警示意义,绝不仅限于TeamViewer或位图处理逻辑:任何系统中,只要存在一次计算并存储大小信息用于后续内存分配,而另存一套尺寸参数用于边界检查的场景,就必须严格保证两套参数的一致性,并且必须使用真实分配的大小作为边界验证的唯一依据。
分配操作和保护操作永远不应该依赖两套不同的算术计算结果。我们在Adobe Acrobat中也发现了同一类漏洞模式,同样是整数溢出导致的越界写入问题,详细分析见我们早先的研究报告:CVE-2026-81983: Adobe Acrobat整数溢出漏洞导致的越界写入分析。
最复杂的攻击链往往源于最简单的编程错误。一个看似无害的32位整数溢出,在特定的系统上下文中,能够转化为完整的远程代码执行攻击能力。这个案例凸显了信任边界验证在安全设计中的极端重要性:任何外部输入都会对系统内部的核心信任假设构成直接威胁;任何不匹配的检查逻辑都会为攻击者提供逻辑绕过路径。
对全球软件开发者而言,这再次证明了防御深度的必要性:即便单个防御层可能被绕过,多层防御仍能显著提高攻击门槛,增强系统整体安全性。
原文:https://remedio.io/research/vulnerability-disclosures/remote-code-execution-in-teamviewer/
- END -
感谢阅读,如果觉得还不错的话,动动手指给个三连吧~
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论