CVE-2025-32715
🚒

CVE-2025-32715

Tags
Vulnerability
RDP
Published
June 26, 2025
Author
Mas0n
近日关注到 MSRC 发布了一个RDC组件的CVE,花了点时间看了看。
Remote Desktop Protocol Client Information Disclosure Vulnerability CWE-125: Out-of-bounds Read
漏洞在 CCO::OnSaveSessionInfoPDU 上,
CCO::OnSaveSessionInfoPDU(CCO *this, tagTS_SAVE_SESSION_INFO_PDU_DATA *pData, ULONG cbData)
pData 实际对应于消息结构 tagTS_SAVE_SESSION_INFO_PDU_DATA
参考 spec
得到以下
struct __unaligned tagTS_SAVE_SESSION_INFO_PDU_DATA { UINT32 infoType; union { struct __unaligned tagTS_LOGON_INFO_VERSION_2 { UINT16 Version; UINT32 Size; UINT32 SessionId; UINT32 cbDomain; UINT32 cbUserName; CHAR Pad[558]; // WCHAR Domain[cbDomain/sizeof(WCHAR)]; // WCHAR UserName[cbUserName/sizeof(WCHAR)]; } LogonLongData; struct __unaligned tagTS_LOGON_INFO_VERSION_1 { UINT32 cbDomain; WCHAR Domain[26]; UINT32 cbUserName; WCHAR UserName[256]; UINT32 SessionId; } LogonData; }; };
当 infoType == 1 时,有以下处理逻辑:
CCO::OnSaveSessionInfoPDU(CCO *this, tagTS_SAVE_SESSION_INFO_PDU_DATA *pData, ULONG cbData) { // ... WCHAR wszDomain[256]; size_t cbDomain; WCHAR wszUserName[256]; size_t cbUserName; cbDomain = pData->LogonLongData.cbDomain; cbUserName = pData->LogonLongData.cbUserName; if ( cbUserName + cbDomain + 0x16 > cbData || (uint32_t)cbDomain > 0x200 || (uint32_t)cbUserName > 0x200 ) { // ... goto FAILED; } memset(wszDomain, 0, sizeof(wszDomain)); memset(wszUserName, 0, sizeof(wszUserName)); memcpy(wszDomain, (char*)pData + 0x224, cbDomain); memcpy(wszUserName, (char*)pData + 0x224 + cbDomain, cbUserName); }
这里的 0x224 对应于 tagTS_LOGON_INFO_VERSION_2 中的 Domain 字段的偏移位置。
乍一看似乎很正常,对 cbDomain cbUserName 进行了约束,同时也校验了数据包的大小。
但是问题恰恰出在校验上:cbUserName + cbDomain + 0x16 > cbData
这里的 0x16 实际并不是 tagTS_LOGON_INFO_VERSION_2 除 variables 外所有字段的固定大小,而是 tagTS_LOGON_INFO_VERSION_1 的大小。
这导致校验存在一个内存空域,
指定:
infoType = 1; cbDomain = 0x200; cbUserName = 0x200; // ... Domain[0x200/sizeof(WCHAR)]; UserName[0x8/sizeof(WCHAR)];
此时 cbData 为 0x244 + 0x200 + 0x8 = 0x44c
带入校验
cbUserName + cbDomain + 0x16 > cbData => 0x200 + 0x200 + 0x16 > 0x44c => true (uint32_t)cbDomain > 0x200 => 0x200 > 0x200 => true (uint32_t)cbUserName > 0x200 => 0x200 > 0x200 => true
满足条件,接下来进入复制阶段
memcpy(wszUserName, (char*)pData + 0x224 + cbDomain, cbUserName);
此时有以下事实
cbDomain = 0x200; cbUserName = 0x200; (char*)pData + 0x224 + 0x200 => (char*)pData + 0x424
看到复制 pData 范围在 [0x424, 0x424+0x200]
但 pData 实际大小为 0x44c,发生越界读取。

修补

修正约束条件。
核心条件:
cbUserName + cbDomain + 0x244 > cbData