概述
SMBGhost (CVE-2020-0796) 是SMBv3.1.1中的压缩函数中的一个安全漏洞,攻击者利用该漏洞可以实现本地权限提升,更多参见
https://blog.zecops.com/vulnerabilities/exploiting-smbghost-cve-2020-0796-for-a-local-privilege-escalation-writeup-and-poc/
近期,研究人员又在同一压缩函数中发现了一个安全漏洞——SMBleed (CVE-2020-1206)。攻击者利用该漏洞可以远程从窃取kernel 内存信息。与SMBGhost漏洞结合形成利用链后,就可以实现远程代码执行攻击。
漏洞分析
SMBleed (CVE-2020-1206)漏洞
SMBleed 漏洞位于srv2.sys SMB
服务器驱动的Srv2DecompressData
函数中,下面是该函数中有漏洞部分的简化版本:
```
typedef struct _COMPRESSION_TRANSFORM_HEADER
{
ULONG ProtocolId;
ULONG OriginalCompressedSegmentSize;
USHORT CompressionAlgorithm;
USHORT Flags;
ULONG Offset;
} COMPRESSION_TRANSFORM_HEADER, *PCOMPRESSION_TRANSFORM_HEADER;
typedef struct _ALLOCATION_HEADER
{
// ...
PVOID UserBuffer;
// ...
} ALLOCATION_HEADER, *PALLOCATION_HEADER;
NTSTATUS Srv2DecompressData(PCOMPRESSION_TRANSFORM_HEADER Header, SIZE_T TotalSize)
{
PALLOCATION_HEADER Alloc = SrvNetAllocateBuffer(
(ULONG)(Header->OriginalCompressedSegmentSize + Header->Offset),
NULL);
If (!Alloc) {
return STATUS_INSUFFICIENT_RESOURCES;
}
ULONG FinalCompressedSize = 0;
NTSTATUS Status = SmbCompressionDecompress(
Header->CompressionAlgorithm,
(PUCHAR)Header + sizeof(COMPRESSION_TRANSFORM_HEADER) + Header->Offset,
(ULONG)(TotalSize - sizeof(COMPRESSION_TRANSFORM_HEADER) - Header->Offset),
(PUCHAR)Alloc->UserBuffer + Header->Offset,
Header->OriginalCompressedSegmentSize,
&FinalCompressedSize);
if (Status < 0 || FinalCompressedSize != Header->OriginalCompressedSegmentSize) {
SrvNetFreeBuffer(Alloc);
return STATUS_BAD_DATA;
}
if (Header->Offset > 0) {
memcpy(
Alloc->UserBuffer,
(PUCHAR)Header + sizeof(COMPRESSION_TRANSFORM_HEADER),
Header->Offset);
}
Srv2ReplaceReceiveBuffer(some_session_handle, Alloc);
return STATUS_SUCCESS;
}
```
Srv2DecompressData
函数会接受客户端发送的压缩消息,分配必要数量的内存,然后将数据解压缩。如果Offset
域不等于0
,就复制位于压缩数据之前部分的数据到分配的缓存的开始位置。
SMBGhost漏洞产生的原因是由于缺乏整数溢出检查。微软已经发布了安全补丁来修复该漏洞。
假的OriginalCompressedSegmentSize
之前,研究人员就通过设置OriginalCompressedSegmentSize
域为一个很大的数导致越界写后整数溢出来利用SMBGhost漏洞。如果将该值设置的笔真实的解压缩数据大一点会怎么样呢?如果,压缩数据解压缩后的大小为x,那么就把OriginalCompressedSegmentSize
设置为x + 0x1000
,会发现:
未初始化的kernel数据会被认为是发送的消息的与部分。
if (Status < 0 || FinalCompressedSize != Header->OriginalCompressedSegmentSize) {
SrvNetFreeBuffer(Alloc);
return STATUS_BAD_DATA;
}
在本例中,假设OriginalCompressedSegmentSize
域的值为x + 0x1000
,FinalCompressedSize
就是x
。事实上,由于SmbCompressionDecompress
函数会导致FinalCompressedSize
的值为x + 0x1000
:
```
NTSTATUS SmbCompressionDecompress(
USHORT CompressionAlgorithm,
PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize,
PUCHAR CompressedBuffer,
ULONG CompressedBufferSize,
PULONG FinalCompressedSize)
{
// ...
NTSTATUS Status = RtlDecompressBufferEx2(
...,
FinalUncompressedSize,
...);
if (status >= 0) {
*FinalCompressedSize = CompressedBufferSize;
}
// ...
return Status;
}
``
FinalCompressedSize
成功解压缩后,就会更新为
CompressedBufferSize `的值,也就是缓存的大小。
漏洞利用
研究人员用来证明该漏洞的SMB消息是SMB2 WRITE
消息。消息结构中含有要写入的字节、flag和可变长度缓存等域。要利用该漏洞,研究人员首先伪造了一个可以指定header
的消息,可变长度缓存中含有未初始化的数据:
// HACK: fake size
if (((Smb2SinglePacket)packet).Header.Command == Smb2Command.WRITE)
{
((Smb2WriteRequestPacket)packet).PayLoad.Length += 0x1000;
compressedPacket.Header.OriginalCompressedSegmentSize += 0x1000;
}
注:研究人员给出的POC需要凭证和可写的共享,但该漏洞可以应用于每个消息,所有可能会在未经认证的情况下被利用。而且泄露的内存是在NonPagedPoolNx pool
中分配的,因为可以控制分配的大小,所以也就可以控制泄露的数据程度。
SMBleed POC源码参见:
https://github.com/ZecOps/CVE-2020-1206-POC
受影响的系统
Windows 10 v1903、1909、2004 都受到该漏洞的影响。在测试过程中,PoC使其中一个Windows 10 1903机器奔溃了。研究人员在分析奔溃的原因时发现,早期的Windows 10 1903 补丁在处理有效的压缩的SMB包时存在空指针引用的问题。
未修复的系统中,存在空指针引用的问题:
修复后,加入了空指针检查:
受影响的系统汇总表如下所示:
SMBleedingGhost
攻击者利用SMBleed漏洞和SMBGhost漏洞可以实现远程代码执行。SMBGhost + SMBleed RCE POC源码参见:https://github.com/ZecOps/CVE-2020-1206-POC
前言 bash 1、在ECB模式的基础上,增强了块与块之间的联系。 2、明文块先与IV XOR运算后,在进行加密,得到的密文充当下一个明文区块的IV... 3、明文块填充方式,如果明文为abcd,长度为4,则需要填充12位,12的十六进制为x0C,在最后加密的…
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论