您好,赛虎网络空间安全实验室欢迎您!

028-37691628

全国咨询热线

您现在所在位置:主页 > 新闻动态 > 行业新闻 >

SMB远程代码执行漏洞 CVE-2020-0796 复现与分析

更新时间:2021-01-27

一、前言

2020年3月10日,自思科talos泄露了一个微软smb v3.1协议漏洞,随即在3月12日,微软公布了紧急修复补丁。

该漏洞编号为CVE-2020-0796,名称为“smbghost”。是一个针对Windows的 SMBv3 客户端与服务端远程代码执行漏洞。其漏洞原理是Microsoft服务器消息块3.1.1(即SMBv3)协议处理某些请求的方式中存在一个远程执行代码漏洞。成功利用此漏洞的攻击者可以获得在目标服务器或客户端上执行代码的能力。SMB 3.1.1协议中处理压缩消息时,对其中数据没有经过安全检查,直接使用会引发内存破坏漏洞,可能被攻击者利用远程执行任意代码。攻击者利用该漏洞无须权限即可实现远程代码执行,受黑客攻击的目标系统只需开机在线即可能被入侵。

 

 

二、漏洞影响

Windows 10 Version 1903 for 32-bit Systems

Windows 10 Version 1903 for x64-based Systems

Windows 10 Version 1903 for ARM64-based Systems

Windows Server, Version 1903 (Server Core installation)

Windows 10 Version 1909 for 32-bit Systems

Windows 10 Version 1909 for x64-based Systems

Windows 10 Version 1909 for ARM64-based Systems

Windows Server, Version 1909 (Server Core installation)

 

 

三、漏洞复现

使用一台安装Windows 10 专业版(版本为1909 Build 18363)的虚拟机作为被攻击机。

在这之前,先使用nmap 扫描,确认被攻击机开放了445 端口的SMB服务

首先复现该漏洞的蓝屏POC脚本 ↓

(https://github.com/eerykitty/CVE-2020-0796-PoC)

被攻击机受到攻击后立即蓝屏并重启

接下来复现利用该漏洞的编写的本地权限提升EXP 。此EXP利用smbghost漏洞将shellcode注入winlogon.exe。在本地执行后可以用来提权。↓

(https://github.com/danigargu/CVE-2020-0796/)

 

 

四、漏洞检测

方法一:

https://github.com/ollypwn/SMBGhost/blob/master/scanner.py

使用socket发送数据包

pkt=b'\x00\x00\x00\xc0\xfeSMB@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$\x00\x08\x00\x01\x00\x00\x00\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x\x00\x00\x00\x02\x00\x00\x00\x02\x02\x10\x02"\x02$\x02\x00\x03\x02\x03\x10\x03\x11\x03\x00\x00\x00\x00\x01\x00&\x00\x00\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\n\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00'

然后通过以下判断代码:

if res[68:70] != b"\x11\x03" or res[70:72] != b"\x02\x00":

        print(f"{ip} Not vulnerable.")

    else:

        print(f"{ip} Vulnerable")

 

如果目标机器存在该漏洞,则会显示 “Vulnerable”

如果不存在,则显示“Not vulnerable”

注:但这种检测方法经过测试,针对微软官方补丁,存在误报。

 

方法二:

通过检测检测系统版本和补丁情况判断 ↓

(https://github.com/T13nn3s/CVE-2020-0796)

 

下面分析代码中的功能模块:

判断系统版本模块:

if ($WindowsVersion -eq 1903) {

        Write-Host "[*] CVE-2020-0976 is applicable to your Windows Version."

    }

    Elseif ($WindowsVersion -eq 1909) {

        Write-Host "[*] CVE-2020-0976 is applicable to your Windows Version."

    }

    Else {

        Write-Host "[+] CVE-2020-0976 is not applicable to your Windows Version." -ForegroundColor Green

        pause

        return

}

 

判断KB4551762补丁是否安装模块:

function CheckIfUpdateIsInstalled {

    Write-Host "[*] Check if KB4551762 is installed..."

 

    $fix = Get-HotFix -Id KB4551762 -ErrorAction SilentlyContinue

 

    if ($fix) {

        Write-Host "[+] *** Windows Update $($fix.HotFixID) is installed on $($fix.InstalledOn). You're not vulnerable ***"

        Write-Host "[+] No workaround needed, you can still customize the SMBv3 compression if you like."

        return

    }

    Else {

        Write-Host "[-] Windows Update $($kb) is not installed."

}

经过测试本方法非常可靠,基本不会误报。

 

 

五、漏洞    分析

漏洞位置:

根据分析,漏洞存在于srv2.sys文件中。并涉及到以下函数:

Srv2DecompressMessageAsync

Srv2DecompressData

Smb2GetHonorCompressionAlgOrder

Smb2SelectCompressionAlgorithm

Smb2ValidateCompressionCapabilities

 

漏洞原因:

该漏洞形成的原因是因为Windows SMB3.1.1客户端及服务端在准备解压数据时,没有对COMPRESSION_TRANSFORM_HEADE结构进行安全校验,导致后续分配buffer时整形溢出。

下图为

SMB2 COMPRESSION_TRANSFORM_HEADER。此可选标头仅对SMB 3.1.1 dialect有效。











可以看到,标头中有两个参数:

OriginalCompressedSegmentSize和Offset / Length。

攻击者可以控制这两个参数,其中,第一个参数为压缩前的数据大小。第二个为压缩数据的长度或者偏移。

攻击发生时,srv2.sys中处理SMBv3压缩数据包的解压函数

Srv2DecompressData

未严格校验数据包中

OriginalCompressedSegmentSize和Offset/Length

字段的合法性。就直接将其相加后作为内存分配的参数。从而在后续调用解压函数SmbCompressionDecompress过程中引发越界。

 

此处参考360博客上分析的代码:

signed __int64 __fastcall RtlDecompressBufferXpressLz(_BYTE *a1, unsigned int a2, _BYTE *a3, unsigned int a4, __int64 a5, _DWORD *a6)

    {

            v9 = &a1[a2];

            ....

            if ( &a1[v21] > v9 )

              return 0xC0000242i64;

            ...

            v33 = a1;

            a1 += v21;

            qmemcpy(v33, v23, v21);

}

根据代码分析,a2的值为OriginalCompressedSegmentSize,v21的值为从smb数据包中解析的解压缩数据的大小,由于该值可由攻击者控制,若该大小大于OriginalCompressedSegmentSize,则会返回0xC0000242错误。
由于之前对长度没有检查,如果我们传入一个很大的OriginalCompressedSegmentSize触发整数溢出,同时v21就可以设置一个极大值,而依然可以通过对decompress size的判断,最终调用qmemcpy拷贝一个极大的size导致缓冲区溢出。

 

 

六、漏洞修复

1. 更新微软官方补丁KB4551762(推荐)↓

https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-0618

 

2. 禁用SMB3.1数据压缩功能

使用管理员权限在命令提示符中执行以下命令即可禁用SMB3.1数据压缩功能:

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

此外,如果要解禁SMB3.1数据压缩功能,使用以下命令:

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

 

3. 关闭SMB服务或封禁445端口

(1)关闭SMB服务

1.运行regedit打开注册表

2.依次依次点击注册表选项

”HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\NetBT\Parameters“

进入NetBT这个服务的相关注册表项。

在右边空白处右击新建“QWORD(64位)值”,然后重命名为“SMBDeviceEnabled”,再把这个子键的值改为0:

 

(2)封禁防火墙445端口

依次点击“开始”,“运行”,输入services.msc,进入服务管理控制台。然后找到server服务,双击进入管理控制页面。把启动类型更改为“禁用”,服务状态更改为“停止”,最后点击应用。

封禁445端口控制面板的“Windows 防火墙”页面左侧找到“高级设置”打开:

在“高级安全 windows 防火墙”页面 左侧 找到 “入站规则”右键点击“新建规则”:

选择“端口”, 点击下一步:

设置445端口:

选择阻止连接 :

勾选 “所有网络”:

任意起名,保存即可:

 

参考来源:

1. https://bbs.pediy.com/thread-258201.htm

2. https://www.mcafee.com/blogs/other-blogs/mcafee-labs/smbghost-analysis-of-cve-2020-0796/

在线客服

ONLINE SERVICE

联系电话

028-37691628

返回顶部