CVE-2020-0609,CVE-2020-0610 |Windows 远程桌面网关 (RD 网关) 远程代码执行漏洞 - 易维网
tohnnystohnnys

安全漏洞

发布时间: 01/14/2020 |最后更新 : 01/16/2020麻省理工学院
本文章“漏洞分析”章节来源Kryptos Logic
CVE-2020-0609 , CVE-2020-0610

当未经身份验证的攻击者使用 RDP 连接到目标系统并发送特制请求时,Windows 远程桌面网关 (RD 网关) 中存在远程代码执行漏洞。此漏洞是预身份验证,不需要用户交互。成功利用此漏洞的攻击者可以在目标系统上执行任意代码。然后,攻击者可以安装程序;查看、更改或删除数据;或创建具有完全用户权限的新帐户。

要利用此漏洞,攻击者需要通过 RDP 向目标系统 RD 网关发送特制请求。

此更新通过更正 RD 网关如何处理连接请求来解决此漏洞。

RDG中的两个漏洞分析

版本区别分析-修复前和修复后

在进行漏洞分析之前,我们需要分析受影响DLL修复前和修复后的版本区别。
A BinDiff of the RDG executable before and after installing the patch.

分析后发现,其中只有一个函数被修改了。首先,RDG支持三种不同的协议,即HTTP、HTTPS和UDP。更新后的函数主要负责处理UDP协议。一般来说,我们可以拿更新前和更新后的函数进行对比,但是这个函数的代码量非常大,而且有多处改动。因此,我们这里直接给出该函数对应的伪代码,并且删除了部分不相关的代码:
Pseudo-code for the UDP handler function

RDG处理的UDP协议允许将数据量大的消息拆分为多个独立的UDP报文,因为UDP属于无连接协议,因此报文到达的顺序不定。。该函数的功能是重组消息,确保每个报文都位于正确的位置上。每个报文中都包含一个Header,其中包含如下字段数据:

fragment_id:报文在序列中的具体位置;

num_fragments:序列中报文的总数量;

fragment_length:报文数据的长度。

消息处理函数使用报文的Header数据来确保收到的消息能以正确的顺序进行重组。然而,该函数在实现上存在漏洞,因此攻击者将能够利用该漏洞来实施攻击。

CVE-2020-0609分析

The packet handler's bounds checking.
memcpy_s()函数会将每个分段数据(fragment)拷贝到重组缓冲区中的一个偏移量地址,重组缓冲区在堆上进行分配,每个分段的偏移量由fragment_idx 1000得到。但是,这里的边界检查逻辑并没有考虑到偏移量这个因素。这里我们可以假设buffer_size= 1000,然后我们发送包含2个分段消息。

1、第1个分段消息(fragment_id=0)长度为1。此时this->bytes_written等于0,因此可以通过边界检查。

2、代码将1字节数据写入偏移量为0的缓冲区地址,bytes_written+ 1。第2个分段消息(fragment_id=1)长度为998,此时this->bytes_written= 1,而1 + 998< 1000,因此可以通过边界检查。

3、代码将998字节数据写入偏移量为1000(fragment_id*1000)的缓冲区地址,导致在缓冲区末尾后写入998个字节。

需要注意的是,这里的报文不一定按顺序到达。如果我们发送的第1个报文中fragment_id=65535(最大值),那么就会被写入偏移量为65535x 1000的地址,也就是缓冲区末尾后的65534000个字节。攻击者可以通过修改fragment_id来将最多999个字节的数据写入缓冲区后偏移量为1到65534000的任何地址。与传统的线性堆溢出漏洞相比,这个漏洞的灵活性更强。攻击者不仅可以利用该漏洞来控制写入数据的大小,而且还能控制写入数据的位置。如果再配合使用其他的技术,攻击者将能够实现更为精准的数据写入,以避免出现不必要的数据崩溃。

CVE-2020-0610分析

The packet handler's tracking of which fragments have been received.
上图中的类对象包含一个由32位无符号整数组成数组,其中每个数组元素对应1个分段数据。当收到一个分段数据后,相应的数据值会从0变为1。当所有元素都被设置为1时,代码就完成了消息重组操作,并开始处理完整的消息。这个数组最多能容纳64个元素,但fragment_id的取值范围为0到65535。代码唯一执行的验证操作就是确保fragment_id值小于num_fragments,但后者同样可以被设置为65535。因此,我们可以将fragment_id设置为65到65535之间的任意值,这样我们就可以在数据边界外写入1(TRUE)。你可能会觉得只将1个值设置为1很难实现远程代码执行,但即使一个小小的改动也可以对程序的正常行为带来巨大的影响。

漏洞检测工具下载

rdg_scanner_cve-2020-0609

如何检测

Example:  python3 rdg_scanner_cve-2020-0609.py 192.168.1.1/24            # vuln scan for cve-2020-0609 on UDP 3391
Example2  python3 rdg_scanner_cve-2020-0609.py 192.168.1.1/24 --webcheck # check webpage for RD gateway
Example3: python3 rdg_scanner_cve-2020-0609.py 192.168.1.1 
Example4: python3 rdg_scanner_cve-2020-0609.py fakewebsiteaddress.com 
Example5: python3 rdg_scanner_cve-2020-0609.py as15169 
Example6: python3 rdg_scanner_cve-2020-0609.py file:hostfile.txt

usage: rdg_scanner_cve-2020-0609.py [-h] [--port PORT] [--webcheck]
                                    [--verbose]
                                    target

No installation required. 
Debian/Kali needs: apt-get install python3-netaddr

漏洞利用篇

蓝屏PoC:
https://github.com/eerykitty/CVE-2020-0796-PoC
使用两台虚拟机作为漏洞演示,一台win10 1903版本,一台是Kali Linux。

python3 CVE-2020-0796.py <IP>

本地提权PoC:
https://github.com/danigargu/CVE-2020-0796
本地普通用户Bypass执行提权exp后弹出cmd窗口,成功获取system权限。

远程利用PoC:
https://github.com/chompie1337/SMBGhost_RCE_PoC
漏洞演示过程:
1、使用msfvenom生成payload

msfvenom  -p windows/x64/meterpreter/bind_tcp  lport=1234 -f py -o evil.py

2、将evil.py 生成的code,替换到exploit.py的USER_PAYLOAD参数,并把参数buf改为USER_PAYLOAD。

root@kali:~# git clone https://github.com/chompie1337/SMBGhost_RCE_PoC.git

3、运行exploit.py

python3 exploit.py -ip 192.168.172.128

4、启动msf监听本地端口(PS:监听端口如果一直收不到shell,可重新运行一次。)

msf5 > use exploit/multi/handler

安全更新

要确定软件版本或版本的支持生命周期,请参阅Microsoft 支持生命周期

缓解措施

如果暂时无法安装补丁,微软当前建议按如下临时解决方案处理:

方法1:禁用SMBv3压缩
禁用SMB 3.0的压缩功能,是否使用需要结合自己业务进行判断。
使用以下PowerShell命令禁用压缩功能,以阻止未经身份验证的攻击者利用SMBv3 服务器的漏洞。

Set-ItemProperty -Path “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” DisableCompression -Type DWORD -Value 1 -Force

用户可通过以下PowerShell命令撤销禁用压缩功能

Set-ItemProperty -Path “HKLM:\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters” DisableCompression -Type DWORD -Value 0 -Force

注:利用以上命令进行更改后,无需重启即可生效;该方法仅可用来防护针对SMB服务器(SMB SERVER)的攻击,无法对SMB客户端(SMB Client)进行防护。

方法2:设置防火墙策略关闭相关端口
SMB的TCP 445端口
NetBIOS名称解析的UDP 137端口
NetBIOS数据图服务的UDP 138端口
NetBIOS会话服务的TCP 139端口

方法3:通过IP安全策略屏蔽危险端口

解决方法

微软已经发布了此漏洞的安全补丁,访问如下链接:
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0796
腾讯电脑管家SMB漏洞修复工具:
http://dlied6.qq.com/invc/QQPatch/QuickFix_SMB0796.exe

常见问题

Q:哪些网络端口容易受到此攻击?
A:此漏洞仅影响 UDP 传输,默认情况下,该传输在 UDP 端口 3391 上运行。

确认

微软平台安全保障与漏洞研究


评论卡