CVE-2019-0708
简要说明:
2019年5月14日,微软发布了本月安全更新补丁,其中包含一个RDP(远程桌面服务)远程代码执行漏洞的补丁更新。远程桌面协议(RDP)本身不易受攻击,但恶意攻击者很可能会针对该漏洞编写一个漏洞利用程序进行恶意利用,更新了安全补丁KB4500705来修复此漏洞,补丁更新地址:https://support.microsoft.com/zh-cn/help/4500705/customer-guidance-for-cve-2019-0708。
受影响版本:
Windows 7
Windows Server 2008
Windows Server 2008 R2
Windows XP
Windows Server 2003
补丁分析
针对补丁修复前后定位有问题的文件。
win7专业版SP1 32位
更新前termdd.sys 04DBF4B01EA4BF25A9A3E84AFFAC9B20 更新后 04B541A51096CF06AFB83E361A2D963D
更新前位于目录C:\Windows\winsxs\x86_machine.inf_31bf3856ad364e35_6.1.7601.17514_none_bc1a57271cf2f285 更新后位于目录C:\Windows\winsxs\x86_machine.inf_31bf3856ad364e35_6.1.7601.24441_none_bc803b2c362becb2
通过bindiff 对 进行对比可以发现,修复前后的区别
主要是 icaBindVirtualChannels、 icaReBindVirtualChannels
Old:
int __stdcall IcaBindVirtualChannels(PVOID P)
{
volatile signed __int32 *v1; // ebx
char *v2; // esi
volatile signed __int32 *v3; // edi
int v5; // [esp+Ch] [ebp-1F0h]
int v6; // [esp+10h] [ebp-1ECh]
int v7; // [esp+14h] [ebp-1E8h]
int v8; // [esp+18h] [ebp-1E4h]
char *v9; // [esp+1Ch] [ebp-1E0h]
int v10; // [esp+20h] [ebp-1DCh]
unsigned int v11; // [esp+24h] [ebp-1D8h]
volatile signed __int32 *v12; // [esp+28h] [ebp-1D4h]
unsigned int v13; // [esp+2Ch] [ebp-1D0h]
int v14; // [esp+30h] [ebp-1CCh]
unsigned int v15; // [esp+34h] [ebp-1C8h]
char v16; // [esp+38h] [ebp-1C4h]
char v17; // [esp+40h] [ebp-1BCh]
v1 = (volatile signed __int32 *)IcaLockConnectionForStack(P);
v9 = &v16;
v12 = v1;
v6 = 3670291;
v7 = 0;
v8 = 0;
v10 = 448;
v11 = 0;
v14 = _IcaCallStack(P, 5, (int)&v6);
if ( v14 >= 0 )
{
v15 = 0;
v13 = v11 / 0xE;
if ( v11 / 0xE > 0 )
{
v2 = &v17;
do
{
if ( _IcaFindVcBind((int)v1, v2 - 8, (int)&v5) == -1 )
{
v14 = _IcaRegisterVcBind((int)v1, v2 - 8, *(unsigned __int16 *)v2, *(_DWORD *)(v2 + 2));
if ( v14 < 0 )
break;
}
v3 = (volatile signed __int32 *)IcaFindChannelByName((int)v1, 5, v2 - 8);
if ( v3 )
{
_InterlockedExchangeAdd(v3 + 2, 1u);
ExEnterCriticalRegionAndAcquireResourceExclusive(v3 + 3);
_IcaBindChannel(v3, 5, *(unsigned __int16 *)v2, *(_DWORD *)(v2 + 2));+
//*(unsigned __int16 *)v2 数据传参可以造成 堆溢出 RCE问题
ExReleaseResourceAndLeaveCriticalRegion(v3 + 3);
IcaDereferenceChannel((PVOID)v3);
IcaDereferenceChannel((PVOID)v3);
v1 = v12;
}
++v15;
v2 += 14;
}
while ( v15 < v13 );
}
}
ExReleaseResourceAndLeaveCriticalRegion(v1 + 3);
if ( !_InterlockedExchangeAdd(v1 + 2, 0xFFFFFFFF) )
_IcaFreeConnection((PVOID)v1);
return v14;
}
New:
int __stdcall IcaBindVirtualChannels(PVOID P)
{
volatile signed __int32 *v1; // ebx
int *v2; // esi
int v3; // eax
char *v4; // edi
int v5; // eax
int v7; // [esp-4h] [ebp-1FCh]
int v8; // [esp+Ch] [ebp-1ECh]
int v9; // [esp+10h] [ebp-1E8h]
int v10; // [esp+14h] [ebp-1E4h]
int v11; // [esp+18h] [ebp-1E0h]
char *v12; // [esp+1Ch] [ebp-1DCh]
int v13; // [esp+20h] [ebp-1D8h]
unsigned int v14; // [esp+24h] [ebp-1D4h]
unsigned int v15; // [esp+28h] [ebp-1D0h]
int v16; // [esp+2Ch] [ebp-1CCh]
unsigned int v17; // [esp+30h] [ebp-1C8h]
char v18; // [esp+34h] [ebp-1C4h]
char v19; // [esp+3Eh] [ebp-1BAh]
v1 = (volatile signed __int32 *)IcaLockConnectionForStack(P);
v12 = &v18;
v9 = 3670291;
v10 = 0;
v11 = 0;
v13 = 448;
v14 = 0;
v16 = _IcaCallStack(P, 5, (int)&v9);
if ( v16 >= 0 )
{
v17 = 0;
v15 = v14 / 0xE;
if ( v14 / 0xE > 0 )
{
v2 = (int *)&v19;
do
{
if ( _IcaFindVcBind((int)v1, (char *)v2 - 10, (int)&v8) == -1 )
{
v16 = _IcaRegisterVcBind((int)v1, (char *)v2 - 10, *((unsigned __int16 *)v2 - 1), *v2);
if ( v16 < 0 )
break;
}
v3 = IcaFindChannelByName((int)v1, 5, (char *)v2 - 10);
v4 = (char *)v3;
if ( v3 )
{
_InterlockedExchangeAdd((volatile signed __int32 *)(v3 + 8), 1u);
ExEnterCriticalRegionAndAcquireResourceExclusive(v3 + 12);
v5 = __stricmp(v4 + 148, "MS_T120"); //判断 虚拟通道名称是否为MS_T120
v7 = *v2;
if ( v5 )
_IcaBindChannel(v4, 5, *((unsigned __int16 *)v2 - 1), v7);
else
_IcaBindChannel(v4, 5, 31, v7); //强制 将 类型设置为31
ExReleaseResourceAndLeaveCriticalRegion(v4 + 12);
IcaDereferenceChannel(v4);
IcaDereferenceChannel(v4);
}
++v17;
v2 = (int *)((char *)v2 + 14);
}
while ( v17 < v15 );
}
}
ExReleaseResourceAndLeaveCriticalRegion(v1 + 3);
if ( !_InterlockedExchangeAdd(v1 + 2, 0xFFFFFFFF) )
_IcaFreeConnection((PVOID)v1);
return v16;
}
主要的处理区别是在 判断 MS_T120 存在时,强制将 通道索引设置为31
v5 = __stricmp(v4 + 148, "MS_T120"); //判断 虚拟通道名称是否为MS_T120
v7 = *v2;
if ( v5 )
_IcaBindChannel(v4, 5, *((unsigned __int16 *)v2 - 1), v7);
else
_IcaBindChannel(v4, 5, 31, v7); //强制 将 通道索引设置为31
漏洞成因
RDP协议通信过程:
网络协议主要流程为:
- 连接初始化
- 基础配置交换
- 通道选择连接
- 启动安全配置
- 安全配置交换
- 可选传输引导
- 数据交换
- 通信结束
主要是指RDP协议网络功能数据传送时通常都包含的各层次,而对于各层次内所实现的单层次连接等功能将做为单独的模块来进行阐述。
网络连接层:RDP协议建立在TCP/IP协议之上,由于传输的数据量比较大,因此在协议的底层首先定义一层网络连接层。它定义了一个完整的RDP数据逻辑包,以避免由于网络包长度过长而被分割使数据丢失。
ISO数据层:在网络连接层之上是ISO数据层,它表示RDP数据的正常连接通信。
虚拟通道层:在ISO数据层之上,RDP协议定义一个虚拟通道层,用以拆分标示不同虚拟通道的数据,加快客户端处理速度,节省占用网络接口的时间。
加密解密层:在虚拟通道层之上,RDP定义一个数据加密解密层。此层用于对所有的功能数据进行加密、解密处理。
功能数据层:在加密解密层之上是功能数据,画面信息,本地资源转换,声音数据,打印数据等所有的功能数据信息都在此层进行处理。另外,根据数据类型的不同,这些数据都有各自不同层次的分割,他们的内部层次结构将在各个功能模块中进行阐述。
连接过程:
1) 客户端连接服务器
2) ISO数据层建立连接
3) 发送初始协议相关信息,接收加密、解密密钥
4) 虚拟通道申请
5) 加密形式发送客户端系统信息,同时验证加密协议
6) 平台软件证书验证
7) 各功能建立连接,各功能数据传输,功能实现
虚拟通道层:在ISO数据层之上,RDP协议定义一个虚拟通道层,用以拆分标示不同虚拟通道的数据,加快客户端处理速度,节省占用网络接口的时间。
虚拟通道层: 虚拟通道层用于在正常的网络连接数据之上,传输虚拟通道的功能数据。此层次的连接另见初始连接模块与通道申请模块,在此只说明正常数据连接时的层次结构。
1) 结构信息:
内容 类型 虚拟通道个数 虚拟通道号 标志 字节数 1 2 2 1 值 0x64/0x68 0x0001 0x03eb至0x03ee 0x70/0xf0 2) 类型说明:
0x64:客户端发送数据 0x68:客户端接收数据
3) 用户号说明:
本次连接的用户号,服务器发送的是0x0001;客户端所发送的值是初始连接时请示通道后服务器同意开通的虚拟个数。
4) 虚拟通道号说明:
虚拟通道号是本层次以上所发送的功能数据所在的虚拟通道号,其由初始连接通道申请建立时确定。
5) 标志说明:
客户端发送的标志为0x70;服务器端发送的标志,当功能数据是图像是(由通道号识别),其值为0x70,当功能数据是其它数据时,其值为0xf0。
构造MS_t120的虚拟通道申请如下
漏洞成因:
正常情况下
MS_T120 SVC名称 为非标准的虚拟通道
在 GENERIC-CONFERENC-CONTROL(虚拟通道层)初始化时,客户端需提供服务端未列入白名单的频道名称,这就造成,对于MS_T120 这个通道 可以给予一个自定义的通道号,这个地方就可以篡改输入数据
在MS_T120通道管理中涉及的组件 如图:
MS_T120引用通道在rdpwsx.dll中创建,堆池在rdpwp.sys中分配。
当在31以外的通道索引的上下文中处理MS_T120引用通道时,堆损坏发生在termdd.sys中。漏洞触发为向目标申请虚拟通道时可造成利用
规则提取
提取向 虚拟通道申请时的二进制数据报
0000 00 0c 29 5e 44 50 00 0c 29 a2 f2 66 08 00 45 00 ..)^DP..)¢òf..E.
0010 01 b0 67 7f 40 00 80 06 00 00 c0 a8 ef 8c c0 a8 .°g.@.....À¨ï.À¨
0020 ef 87 c0 20 0d 3d 00 1f 4d 58 c0 bf 81 c0 50 18 ï.À .=..MXÀ¿.ÀP.
0030 01 00 62 08 00 00
以下为rdp 数据 03 00 01 88 02 f0 80 7f 65 82 ..b........ð..e.
0040 01 7c 04 01 01 04 01 01 01 01 ff 30 19 02 01 22 .|........ÿ0..."
0050 02 01 02 02 01 00 02 01 01 02 01 00 02 01 01 02 ................
0060 02 ff ff 02 01 02 30 19 02 01 01 02 01 01 02 01 .ÿÿ...0.........
0070 01 02 01 01 02 01 00 02 01 01 02 02 04 20 02 01 ............. ..
0080 02 30 1c 02 02 ff ff 02 02 fc 17 02 02 ff ff 02 .0...ÿÿ..ü...ÿÿ.
0090 01 01 02 01 00 02 01 01 02 02 ff ff 02 01 02 04 ..........ÿÿ....
00a0 82 01 1b 00 05 00 14 7c 00 01 81 12 00 08 00 10 .......|........
00b0 00 01 c0 00 44 75 63 61 81 04 01 c0 d8 00 04 00 ..À.Duca...ÀØ...
00c0 08 00 00 01 00 01 01 ca 03 aa 04 09 00 00 ce 0e .......Ê.ª....Î.
00d0 00 00 72 64 70 79 00 00 00 00 00 00 00 00 00 00 ..rdpy..........
00e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00f0 00 00 04 00 00 00 00 00 00 00 0c 00 00 00 00 00 ................
0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ca ...............Ê
0140 01 00 00 00 00 00 20 00 07 00 01 00 00 00 00 00 ...... .........
0150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0180 00 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 ................
0190 00 00 02 c0 0c 00 1b 00 00 00 00 00 00 00 03 c0 ...À...........À
01a0 20 00 02 00 00 00 4d 53 5f 54 31 32 30 00 00 00 .....MS_T120...
01b0 00 00 64 72 64 79 6e 76 63 00 00 00 00 00 ..drdynvc.....
则提取
TPKT 标识 content:” | 03 00 | ”; offset:0; depth:2; |
ISO层标识content:” | 02 f0 | ”; distance:2; within:2; |
层标识content:” | 00 05 00 14 7c 00 01 | ”; within:512; |
虚拟通道标志位:content:” | 03 c0 | ”; distance:3; within:384; |
虚拟通道名称: content:”MS_T120 | 00 | ”; |
可以完整识别申请MS_t120虚拟通道 的行为
snort 规则
alert tcp any any -> any 3389 (msg:"{'id':5, 'threat_judge':'Threat', 'threat_type':['Exploits'], 'attack_direction':{'Source':'Attacker','Obj':'Victim'}, 'attack_phase':'Invasion', 'behavior':['VulnerabilityIntrusion'], 'family':'Unknown', 'description':'Command', 'cve_number':'CVE-2019-0708','threat_level':'HighRisk', 'apt_org':'', 'author':'DC', 'extract_date':'20190520', 'sign_source':'ArtificialExtraction', 'refer':[], 'remarks':'NCC GROUP RDP connection setup with MS_T120 channel, potential CVE-2019-0708'}"; flow:to_server,established; content:"|03 00|"; offset:0; depth:2; content:"|02 f0|"; distance:2; within:2; content:"|00 05 00 14 7c 00 01|"; within:512; content:"|03 c0|"; distance:3; within:384; content:"MS_T120|00|"; distance:6; within:372; threshold: type limit, track by_src, count 2, seconds 600; classtype:Exploits; reference:url,portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708; sid:1; rev:1;)
相关链接: https://securingtomorrow.mcafee.com/other-blogs/mcafee-labs/rdp-stands-for-really-do-patch-understanding-the-wormable-rdp-vulnerability-cve-2019-0708/ https://blog.csdn.net/songshiMVP1/article/details/46441929 https://docs.microsoft.com/en-us/windows/desktop/TermServ/terminal-services-virtual-channels