通过显示器控制命令集(MCCS)入侵HP显示器(CVE-2023-5449)

本文详细介绍了如何利用显示器控制命令集(MCCS)标准协议,在数十款HP显示器中发现并利用CVE-2023-5449漏洞。文章涵盖MCCS协议基础、HP专有VCP代码实现、防盗机制的安全缺陷,以及通过ddcset工具进行漏洞利用的实际步骤。

通过显示器控制命令集(MCCS)入侵HP显示器(CVE-2023-5449)

2023年10月31日 · 1702词 · 8分钟阅读

你是否曾好奇显示器的软件如何通过简单的显示线缆改变亮度等各种设置?实际上,这依赖于一个标准协议,而该协议可能引发有趣的安全漏洞。以下是我如何在数十款HP显示器中发现并利用CVE-2023-5449的过程。

显示器软件

某天,我将电脑连接到一台HP显示器。令人烦恼的是,Windows自动安装了HP Display Center软件,没有任何提示,可能是因为它是受信任的Windows Store应用。后来我注意到,即使使用其他品牌的显示器,HP Display Center仍能交互并控制某些基本设置(如亮度)。

出于好奇,我决定研究该软件的内部机制。幸运的是,它是一个.NET Framework应用,可以轻松反编译为接近原始的C#代码。在代码中,我注意到一些有趣的函数在显示设置改变时被调用,如ExecuteSetVcp。这些函数进而调用底层的Windows API,推测是处理实际的硬件级通信。

经过搜索,我发现Vcp指的是虚拟控制面板。在显示器控制命令集(MCCS)协议中,每个VCP对应一个特定的显示器设置,如亮度VCP、对比度VCP等。但首先,我需要更深入地理解MCCS。

显示器控制命令集(MCCS)

我们能够相对互换地使用显示器而无需更换线缆、驱动程序等,这得益于视频电子标准协会(VESA)制定的各种标准。是的,那个制定VESA挂架标准的VESA,除了物理标准外,还规定了固件和软件标准,如MCCS。

顾名思义,MCCS规定了连接到显示器的主机如何通过各种命令控制显示器。MCCS运行在底层的显示数据通道命令接口(DDC/CI)标准之上,该标准可在HDMI等多种线缆上实现。

具体来说,MCCS定义了三种类型的VCP控制:

  • 连续型:值从0到指定最大值,如亮度(0到100)。
  • 非连续型:值在有限集合内(即枚举/布尔型),如颜色预设。
  • 表格型:数据块(自定义结构体)。例如,“源时序模式”VCP具有5字节数据结构:DMT时序模式标志(0)、CEA DTV时序模式标志(1)、CVT描述符字节(2-4)。是的,这些缩写词我都没去查。

此外,这些控制可以是只读、只写或读写(这一点后面很重要)。你可以查看已发布的MCCS文档以获取完整的VCP代码列表。

要设置可写的VCP控制,Windows提供了以下API:

1
2
3
4
5
_BOOL SetVCPFeature(
  [in] HANDLE hMonitor,     // 显示器实例句柄
  [in] BYTE   bVCPCode,     // VCP控制代码
  [in] DWORD  dwNewValue    // 新的VCP控制代码值
);

尽管MCCS预定义了从控制代码0x00到0xDF的许多常见VCP控制,但它也为制造商特定控制留出了空间:

控制代码E0h到FFh的32个代码已分配,允许制造商在定义的VCP代码不提供所需功能或添加功能被视为专有时,发布自己的特定控制。

警告:使用这些代码可能导致不兼容和/或不可预测的行为。例如:考虑两个显示制造商选择相同的“制造商VCP代码”用于不同功能(或同一功能的不同实现),但用户选择不使用为其特定显示器提供或推荐的特定软件支持——他可能使用通用MCCS支持应用、操作系统内置的本机支持或用于不同显示器型号的MCCS支持应用。在这种情况下, resulting行为不可预测,范围从不支持使用“制造商VCP代码”的功能到不正确控制和调整功能。在所有情况下,这可能导致用户烦恼和服务呼叫,极端情况下可能导致用户无法将显示器恢复正常操作。

建议谨慎使用这些代码,仅在严格必要时使用。

尽管有此严厉警告,但正如我在iCalendar标准中发现的那样,供应商往往为了在共同标准上区分产品而偏向冒险。例如,你会发现显示器远不止显示漂亮图片——它们可以集成网络摄像头、麦克风等。

显示器支持的某些信息在初始化期间通过能力字符串发送,允许软件了解该显示器支持哪些VCP控制。

HP的专有VCP代码

你可能注意到,只有16个不同的VCP代码分配给制造商特定控制,实际上添加新控制的空间并不大。

然而,HP对此有一个巧妙的解决方案。

对于连续控制,它们的代码遵循<VCP代码> <值>的常规模式。

但对于非连续控制,这浪费了字节,因为枚举通常只取少数可能值。例如,可能有几个颜色配置文件对应特定字节值:游戏(0)、电影(1)、暖色(2)、冷色(3)。但一个字节最多可取256个值。

相反,对于专有的非连续控制,HP在一个全能VCP代码内创建了子VCP代码。设置此VCP控制时,值范围可以从SetColorProfileGaming(0)、SetColorProfileMovie(1)、SetColorProfileWarm(2)、SetColorProfileCool(3),然后包括其他非连续控制,如SetScreenOrientation0(4)、SetScreenOrientation90(5)、SetScreenOrientation180(6)等。这样,X个非连续控制不是占用X个宝贵的专有控制代码,而是仅占用1个。

防盗机制

从固件中反推这些代码很困难,固件主要包含显示器芯片组特定(Genesis)指令。Red Balloon Security之前对在DDC上运行的专有“GProbe”协议进行过一些研究,这说服我不要走那条路。

相反,由于显示器控制软件易于获取,反推客户端并从函数名、使用GUI时的动态调试和日志消息中找出VCP控制代码的功能要容易得多。

我从GUI中注意到的一个有趣功能是HP的防盗机制。用户可以在显示器上设置4到6位PIN码,这样如果显示器被盗并连接到新计算机而未输入PIN码,5分钟后屏幕会变暗并显示消息“防盗模式已启用”。

为支持此功能,HP实现了以下控制命令:

  • TheftTimeOut(251):连续值,表示在未输入PIN码时触发反盗机制前的分钟数。
  • TheftLowPin(252):连续值,表示PIN码的低3位。
  • TheftHighPin(253):连续值,表示PIN码的高3位。
  • TheftDeterrence(250):非连续值,表示防盗机制状态。可以是TheftDisabled(0)、TheftEnabledConsumer(1)或TheftEnabledEnterprise(2)。

启用反盗时,HP Display Center软件接收用户输入的PIN码,然后发送以下写MCCS命令:

  • TheftLowPin = LowPin:显示器设置LowPin。
  • TheftHighPin = HighPin:显示器设置HighPin。
  • TheftDeterrence = TheftEnabledConsumer:显示器开启反盗。

关闭反盗时,它发送以下写MCCS命令:

  • TheftLowPin = LowPin:显示器检查LowPin。
  • TheftHighPin = HighPin:显示器检查HighPin。
  • TheftDeterrence = TheftDisabled:如果前两步检查正确,显示器关闭反盗。

在固件端,当显示器尚未接收正确的TheftLowPin和TheftHighPin命令时,TheftDeterrence正确配置为只读(RO)。不幸的是,TheftLowPin和TheftHighPin控制命令值未设置为只写(WO),而是实际可读写(RW)。这允许攻击者在反盗触发时实际读取PIN码值。

需要注意的是,HP的实现对读写解释相当宽松。例如,在尝试解锁显示器时,使用写命令发送PIN值,但这些值实际上不会覆盖存储的PIN值。只是为了通过MCCS发送值,必须发送写命令。

MCCS模糊测试与利用

当然,要实际发送恶意控制命令序列,你仍需使用底层API与显示器通信。用C++自定义编码可能相当麻烦。幸运的是,通过Rust的ddcset项目(https://github.com/arcnmx/ddcset-rs)已经做了一些工作,使得操作通过DDC/CI发送的消息变得容易。这是开发自己的自定义工具和模糊测试器的良好基础。

对于像防盗这样的简单漏洞,可以直接发送消息进行利用。

  1. 使用HP Display Center软件,进入高级选项卡,将PIN设置为123123并启用反盗。
  2. 将显示器连接到另一台计算机。你有5分钟时间,之后反盗将触发。
  3. 运行ddcset -b winapi getvcp 252读取TheftLowPin。它应返回:
    1
    2
    3
    
    Display on winapi:
            ID: Generic PnP Monitor
            Feature 0xfc = 123 / 65535
    
  4. 运行ddcset -b winapi getvcp 253读取TheftHighPin。它也应返回相同值。

这证明你已成功从“被盗”显示器读取PIN码。如果反盗触发,只需使用HP Display Center输入泄露的PIN码即可。

结论

我与HP协调披露了CVE-2023-5449。观察修补硬件(尤其是像显示器这样的专用硬件)的难度有多大,很有趣。

这个简单漏洞仅触及了专有MCCS VCP控制中可能发现的更有趣漏洞的表面,特别是如果使用表格类型值,更可能触发内存损坏问题。正如VESA警告的那样,这可能导致显示器永久损坏。

随着显示器在硬件和软件上添加更多功能(如集成网络摄像头),我怀疑我们可能会开始在这一领域看到更严重的漏洞出现。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计