CVE-2020-0796 分析

CVE-2020-0796

3月13日 凌晨左右 ,微软放了这个漏洞的补丁…所以稍微分析一下他的补丁

Bindiff

通过 bindiff 比较发现一个函数,且名字也蛮可疑的..

这个函数名叫 Srv2DecompressData 实际上和漏洞描述其实也差不多..

似乎是加了检查..我们 打开IDA来比对一下 两者的差别..

补丁

左边是有漏洞的版本,右边是 Patch 后的版本 .. 比对了一下发现似乎增加了一个检查..尤其是增加的一个叫

RtlULongAdd 的函数..

1
RtlULongAdd(ULONG ulAugend, ULONG ulAddend, ULONG *pulResult)

该函数的参数是 两个似乎 recve 的数据 以及一个变量..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NTSTATUS __stdcall RtlULongAdd(ULONG ulAugend, ULONG ulAddend, ULONG *pulResult)
{
ULONG v3; // eax
ULONG v4; // edx
NTSTATUS result; // eax

v3 = ulAugend + ulAddend;
v4 = -1;
if ( v3 >= ulAugend )
v4 = v3;
result = v3 < ulAugend ? 0xC0000095 : 0;
*pulResult = v4;
return result;
}

看了一下这个 判断了 ulAugend + ulAddend 相加后的和是否小于其中一个 加数..如果是则将其中一个赋值给返回值..从这里大概能初步判断是个什么漏洞了..基本能猜测是个 整型溢出..

漏洞

我们来看一下未打补丁的版本…

看了一下..这里是将原本个值直接相加,并没有进行checkl… 然后分配内存..如果有问题 …应该是这里分配的内存太小..导致后续的缓冲区溢出吧?

由于我对这两个值不是很熟悉..所以这个时候开始查资料..

这个时候发现已经有人发文了…参考链接最后贴后面..

可以知道的是..这里的值一个是 OriginalCompressedSegmentSize 一个是 Offset/Length,他们 描述如下:

  1. OriginalCompressedSegmentSize (4 bytes) The size, in bytes, of the uncompressed data segment.
  2. Offset/Length (4 bytes) If SMB2_COMPRESSION_FLAG_CHAINED is set in Flags field, this field MUST be interpreted as Length. The length, in bytes, of the compressed payload. Otherwise, this field MUST be interpreted as Offset. The offset, in bytes, from the end of this structure to the start of compressed data segment.

然后做了什么事情呢?

看代码,将分配的内存 用 SmbCompressionDecompress 这个函数进行处理

我在 srvnet 里找到了 SmbCompressionDecompress 这个函数

然后又调用了 RtlDecompressBufferEx2 这个函数..最后调的是 RtlDecompressBufferXpressLz 这个函数…

这个函数在ntoskrnl. exe

这个函数做的是事情就是..

memcpy(ptr,src,len)

ptr 是由 SrvNetAllocateBuffer分配的UncompressBufferlen 是从smb 包解析的解压数据的大小,这个值是攻击者可控的, 由于前面没有检查..所以我们传入一个很大的值,使其触发整型溢出.分配一个较小的内存…此时 len又是一个大的值..所以导致了缓冲区溢出

参考链接

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/1d435f21-9a21-4f4c-828e-624a176cf2a0

http://blogs.360.cn/post/CVE-2020-0796.html