SMBGhost漏洞(CVE2020-0796)简单分析

0x00 漏洞描述

3 月 10 日:微软发布安全通告 ADV200005,称 SMBv3 协议在处理某些请求的方式中存在代码执行漏洞,并提供了缓解措施。
3 月 12 日:微软正式发布 CVE-2020-0796 安全通告和漏洞修复补丁。
 
CVE-2020-0796是Windows 10 1903/1909的新SMB3压缩功能中的错误。
SMB协议版本3.1.1引入了一种功能,即客户端或服务器可以发布压缩功能,并有选择地压缩SMB3消息。
使用此功能协商会话后,客户端或服务器可以选择压缩某些SMB消息。为此,整个SMB包会被压缩,并且生成的文件头会被前置。此标头是一个小的(16字节)结构:魔术值,未压缩的数据大小,使用的压缩算法和偏移值。
CVE-2020-0796是由该偏移量大小中缺少边界检查导致的,该偏移量大小会被直接传递给多个子例程。传入较大的值将导致缓冲区溢出,并使内核崩溃。通过进一步的工作,可以将其开发为远程代码执行类型等的漏洞利用程序。
 
漏洞影响版本:
  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)
 
0x01 漏洞分析

1.分析环境搭建及配置
配置目标机(虚拟机): Windows版本:1909,未安装安全更新补丁(KB4551762)
查看其ip:
SMBGhost漏洞(CVE2020-0796)简单分析_第1张图片
配置内核调试,管理员权限启动cmd,输入以下命令
SMBGhost漏洞(CVE2020-0796)简单分析_第2张图片
 
配置内核调试主机(宿主机):
配置符号表:
SMBGhost漏洞(CVE2020-0796)简单分析_第3张图片
SMBGhost漏洞(CVE2020-0796)简单分析_第4张图片
 
配置完成后,重启虚拟机即可开始调试内核
SMBGhost漏洞(CVE2020-0796)简单分析_第5张图片
 
 
 
2.打开Wireshark,进行抓包
 
3.触发蓝屏,进行调试。
(将目标机关闭防火墙) SMBGhost漏洞(CVE2020-0796)简单分析_第6张图片
采用蓝屏poc:
https://github.com/maxpl0it/Unauthenticated-CVE-2020-0796-PoC/blob/master/crash.py
触发蓝屏:虚拟机成功挂掉
SMBGhost漏洞(CVE2020-0796)简单分析_第7张图片
 
Wireshark抓包如下:
SMBGhost漏洞(CVE2020-0796)简单分析_第8张图片
SMBGhost漏洞(CVE2020-0796)简单分析_第9张图片
 
使用!analyze -v
KEY_VALUES_STRING: 1


    Key  : Analysis.CPU.Sec
    Value: 5


    Key  : Analysis.DebugAnalysisProvider.CPP
    Value: Create: 8007007e on DESKTOP-JT38GVK


    Key  : Analysis.DebugData
    Value: CreateObject


    Key  : Analysis.DebugModel
    Value: CreateObject


    Key  : Analysis.Elapsed.Sec
    Value: 61


    Key  : Analysis.Memory.CommitPeak.Mb
    Value: 61


    Key  : Analysis.System
    Value: CreateObject




ADDITIONAL_XML: 1


BUGCHECK_CODE:  50


BUGCHECK_P1: ffffc80d40cf0c1f


BUGCHECK_P2: 0


BUGCHECK_P3: fffff80414c3cee7


BUGCHECK_P4: 2


READ_ADDRESS:  ffffc80d40cf0c1f Nonpaged pool


MM_INTERNAL_CODE:  2


PROCESS_NAME:  System


TRAP_FRAME:  ffffc68f9c9b2b90 -- (.trap 0xffffc68f9c9b2b90)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=ffffc68f9c9b2d58 rbx=0000000000000000 rcx=ffffc68f9c9b2d50
rdx=0000000000000001 rsi=0000000000000000 rdi=0000000000000000
rip=fffff80414c3cee7 rsp=ffffc68f9c9b2d20 rbp=ffffc68f9c9b2d70
r8=0000000000000000  r9=0000000000000033 r10=fffff80414c3ce90
r11=0000000000000000 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei pl zr na po nc
nt!RtlDecompressBufferLZNT1+0x57:
fffff804`14c3cee7 0fb71e          movzx   ebx,word ptr [rsi] ds:00000000`00000000=????
Resetting default scope


STACK_TEXT:  
ffffc68f`9c9b2148 fffff804`148ad492 : ffffc80d`40cf0c1f 00000000`00000003 ffffc68f`9c9b22b0 fffff804`1472bf20 : nt!DbgBreakPointWithStatus
ffffc68f`9c9b2150 fffff804`148acb82 : fffff804`00000003 ffffc68f`9c9b22b0 fffff804`147d7ce0 00000000`00000050 : nt!KiBugCheckDebugBreak+0x12
ffffc68f`9c9b21b0 fffff804`147c3917 : fffff804`14a681b8 fffff804`148d6fe5 ffffc80d`40cf0c1f ffffc80d`40cf0c1f : nt!KeBugCheck2+0x952
ffffc68f`9c9b28b0 fffff804`14807b0a : 00000000`00000050 ffffc80d`40cf0c1f 00000000`00000000 ffffc68f`9c9b2b90 : nt!KeBugCheckEx+0x107
ffffc68f`9c9b28f0 fffff804`146d01df : ffffc80c`43764000 00000000`00000000 00000000`00000000 ffffc80d`40cf0c1f : nt!MiSystemFault+0x18fafa
ffffc68f`9c9b29f0 fffff804`147d169a : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000054 : nt!MmAccessFault+0x34f
ffffc68f`9c9b2b90 fffff804`14c3cee7 : 00000000`00000000 00000000`00001100 ffffc80c`3feff8c0 00000000`00001000 : nt!KiPageFault+0x35a
ffffc68f`9c9b2d20 fffff804`1466e666 : ffffc80d`417bc04f ffffc80c`3feff8c0 ffffc80d`417bc04f fffff804`1466e5da : nt!RtlDecompressBufferLZNT1+0x57
ffffc68f`9c9b2db0 fffff804`1944e0bd : 00000000`00000002 00000000`00000033 00000000`ffffffff fffff804`00000000 : nt!RtlDecompressBufferEx2+0x66
ffffc68f`9c9b2e00 fffff804`194f7f41 : ffffc80c`00010020 ffffc80c`417bd150 00000000`00000001 00000000`ffffffff : srvnet!SmbCompressionDecompress+0xdd
ffffc68f`9c9b2e70 fffff804`194f699e : 00000000`00000000 ffffc80c`40cf06a0 00000000`00000002 ffffffff`ffffffff : srv2!Srv2DecompressData+0xe1
ffffc68f`9c9b2ed0 fffff804`19539a7f : ffffc80c`40cf06b0 ffffc80c`3fe31001 ffffc80c`3fe31000 fffff804`14739e00 : srv2!Srv2DecompressMessageAsync+0x1e
ffffc68f`9c9b2f00 fffff804`147c704e : ffffc68f`9c9b0028 ffffc68f`9ded7901 ffffffff`ee1e5d00 ffffc68f`9c9b2fd1 : srv2!RfspThreadPoolNodeWorkerProcessWorkItems+0x13f
ffffc68f`9c9b2f80 fffff804`147c700c : ffffc68f`9c9b2fd1 ffffc80c`3fe31040 ffffc68f`9c9b3000 fffff804`146c745e : nt!KxSwitchKernelStackCallout+0x2e
ffffc68f`9ded78f0 fffff804`146c745e : ffffc68f`9c9b2fd1 ffffc68f`9c9b3000 00000000`00000001 00000000`00000000 : nt!KiSwitchKernelStackContinue
ffffc68f`9ded7910 fffff804`146c725c : fffff804`19539940 ffffc80c`41fdd220 00000000`00000002 00000000`00000000 : nt!KiExpandKernelStackAndCalloutOnStackSegment+0x18e
ffffc68f`9ded79b0 fffff804`146c70d3 : 00000000`00000080 00000000`00000088 ffffc80c`3fe31040 ffffc68f`9ded7b00 : nt!KiExpandKernelStackAndCalloutSwitchStack+0xdc
ffffc68f`9ded7a20 fffff804`146c708d : fffff804`19539940 ffffc80c`41fdd220 ffffc80c`41fdd220 00000000`00000088 : nt!KeExpandKernelStackAndCalloutInternal+0x33
ffffc68f`9ded7a90 fffff804`195397d7 : ffffc80c`00000000 00000000`00000000 ffffb483`555434b0 00000000`00000000 : nt!KeExpandKernelStackAndCalloutEx+0x1d
ffffc68f`9ded7ad0 fffff804`14d174a7 : ffffc036`55f09c90 ffffc80c`3fe31040 00000203`64d9e500 00000000`00000000 : srv2!RfspThreadPoolNodeWorkerRun+0x117
ffffc68f`9ded7b30 fffff804`14737925 : ffffc80c`3fe31040 fffff804`14d17470 ffffb483`555434b0 00000000`00000000 : nt!IopThreadStart+0x37
ffffc68f`9ded7b90 fffff804`147cad5a : fffff804`139bd180 ffffc80c`3fe31040 fffff804`147378d0 00000000`00000001 : nt!PspSystemThreadStartup+0x55
ffffc68f`9ded7be0 00000000`00000000 : ffffc68f`9ded8000 ffffc68f`9ded1000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x2a




SYMBOL_NAME:  srvnet!SmbCompressionDecompress+dd


MODULE_NAME: srvnet


IMAGE_NAME:  srvnet.sys


STACK_COMMAND:  .thread ; .cxr ; kb


BUCKET_ID_FUNC_OFFSET:  dd


FAILURE_BUCKET_ID:  AV_R_INVALID_srvnet!SmbCompressionDecompress


OS_VERSION:  10.0.18362.1


BUILDLAB_STR:  19h1_release


OSPLATFORM_TYPE:  x64


OSNAME:  Windows 10


FAILURE_ID_HASH:  {4320f3dd-f397-f147-9d97-e2ca1e080673}


Followup:     MachineOwner
---------

 

查看栈回溯如下:
SMBGhost漏洞(CVE2020-0796)简单分析_第10张图片
 
 
4.上ida
加载srv2.sys
查看Srv2DecompressMessageAsync函数,在该函数中调用了Srv2DecompressData函数
同时查看srv2DecompressMessageAsync函数的交叉引用
SMBGhost漏洞(CVE2020-0796)简单分析_第11张图片
可以看到在Srv2ReceiveHandler中调用了它
而Srv2ReceiveHandler函数,是smb调用来进行数据包接收的,查看其反汇编,可以看到,smb协议根据protocolID来设置不同的处理函数,而1112364028即0x424D53FD,根据微软MS-SMB2协议文档,SMBCompression Transform Header的结构
SMBGhost漏洞(CVE2020-0796)简单分析_第12张图片
查看Srv2ReceiveHandler函数,
1.SMB首先调用srv2!Srv2ReceiveHandler函数接收数据包,并根据ProtocolId设置对应的处理函数:
SMBGhost漏洞(CVE2020-0796)简单分析_第13张图片
如果判断数据包中为压缩的数据(ProtocolID = 0xfc4d5342 即 0xFC,‘S’,‘M’,‘B’),则调用处置函数:Srv2DecompressMessageAsync函数。该函数继续调用Srv2DecompressData函数
SMBGhost漏洞(CVE2020-0796)简单分析_第14张图片
 
继续跟进Srv2DecompressData函数,该函数进行buffer申请,然后调用SmbCompressDecompress进行解压缩。
buffer申请函数:SrvNetAllocateBuffer函数
SMBGhost漏洞(CVE2020-0796)简单分析_第15张图片
而攻击者可以控制OriginalCompressedSegmentSize和offsetOrLength这两个参数。
在Srv2DecompressData函数中可以看到数据处理的部分:在进行buffer分配时,会调用SrvNetAllocateBuffer进行分配。但是在调用时,并未对OriginalCompressedSegmentSize和Offset/Length的长度进行任何检查,对二者相加的和也未进行安全检查,此处就存在一个整数溢出。
SMBGhost漏洞(CVE2020-0796)简单分析_第16张图片
SMBGhost漏洞(CVE2020-0796)简单分析_第17张图片
SMBGhost漏洞(CVE2020-0796)简单分析_第18张图片
 
srv2!Srv2DecompressData函数调用位于srvnet模块中的SmbCompressionDecompress函数。而该函数又调用了ntoskrnl.exe函数中的nt!RtlDecompressBufferXpressLz函数,最后实际调用的是qmemcpy进行内存拷贝,于是就造成了溢出。
SMBGhost漏洞(CVE2020-0796)简单分析_第19张图片
至此,漏洞原理已分析清楚,只要构造OriginalCompressedSegmentSize与Offset之和能产生整数溢出就有可能触发漏洞。
 
附录:
动态调试流程:
1.设置initial break重新启动
SMBGhost漏洞(CVE2020-0796)简单分析_第20张图片
 
2.设置加载断点
3.停下后,在srv2DecompressData处下断点:
 
(经过多次试验!终于停下来了!)
SMBGhost漏洞(CVE2020-0796)简单分析_第21张图片
 
4.单步跟踪: 单步跟踪来到srv2!Srv2DecompressData + 0x68地址处,往下继续执行,当执行到
mov rax, qword ptr [rsp+30h]处观察rsp+30处的内存可以看到正好是发送的构造数据包的头部
SMBGhost漏洞(CVE2020-0796)简单分析_第22张图片
SMBGhost漏洞(CVE2020-0796)简单分析_第23张图片
 
往下有调用SrvNetAllocateBuffer函数,根据函数调用原则,先将函数参数入栈再进行调用。
 
SMBGhost漏洞(CVE2020-0796)简单分析_第24张图片
由前面反汇编可得,该SrvNetAllocateBuffer函数主要进行内存分配。其中rcx中存放的值恰好是OriginalCompressedSegmentSize与offset之和。(故上述根据反编译进行变量法分析的思路是正确的)
SMBGhost漏洞(CVE2020-0796)简单分析_第25张图片
故缓冲区分配的大小为0x31
 
5.跟进分析SmbCompressionDecompress函数
SMBGhost漏洞(CVE2020-0796)简单分析_第26张图片
该函数中,rcx为第一个参数,指定了使用的压缩算法的类型,rdx为第二个参数,指定了压缩数据存放的位置。
 
6.在nt!RtlDecompressBufferLZNT1处(即奔溃点)设置断点
SMBGhost漏洞(CVE2020-0796)简单分析_第27张图片
(此处忘记截图了,借用一开始分析的图片:)
总结:大数据到小缓冲区于是造成了溢出。
 
 
 
 
 
0x02 漏洞利用

1.提权原理分析
SMBGhost漏洞(CVE2020-0796)简单分析_第28张图片
原理:
漏洞存在于在srv2.sys驱动中,由于SMB没有正确处理压缩的数据包,在解压数据包的时候调用函数Srv2DecompressData处理压缩数据时候,对压缩数据头部压缩数据大小OriginalCompressedSegmentSize和其偏移Offset的没有检查其是否合法,导致其相加可分配较小的内存,后面调用SmbCompressionDecompress进行数据处理时候使用这片较小的内存可导致拷贝溢出或越界访问,而在执行本地程序的时候,可通过获取当前本地程序的token+0x40的偏移地址,通过发送压缩数据给SMB服务器,之后此偏移地址在解压缩数据时候拷贝的内核内存中,通过精心构造的内存布局在内核中修改token将权限提升。
(1)验证程序首先创建到SMS server的会话连接(记为session)。
(2)验证程序获取自身token数据结构中privilege成员在内核中的地址(记tokenAddr)。
(3)验证程序通过session发送畸形压缩数据(记为evilData)给SMB server触发漏洞。其中,evilData包含tokenAddr、权限数据、溢出占位数据。
(4) SMS server收到evilData后触发漏洞,并修改tokenAddr地址处的权限数据,从而提升验证程序的权限。
(5)验证程序获取权限后对winlogon进行控制,来创建system用户shell。
 
源码分析:
1.构造socket用于发送smb数据包,目的地址设为本机,建立session
SMBGhost漏洞(CVE2020-0796)简单分析_第29张图片
 
2.获取token
SMBGhost漏洞(CVE2020-0796)简单分析_第30张图片
 
构造数据:
SMBGhost漏洞(CVE2020-0796)简单分析_第31张图片
3.poc接着调用RtCompressBuffer来压缩数据, 压缩数据包的主要内容是0x1108*A+(ktoken+0x40)。
SMBGhost漏洞(CVE2020-0796)简单分析_第32张图片
 
经压缩后的数据长度0x13,之后这段压缩数据除去压缩数据段头部外,发送出去的压缩数据前面将会连接两个相同的值0x1FF2FFFFBC,而这两个值将会是提权的关键。此外,构造的smb header中,OriginalCompressedSegmentSize为0xffffffff,offset为0x10。
SMBGhost漏洞(CVE2020-0796)简单分析_第33张图片
 
SMBGhost漏洞(CVE2020-0796)简单分析_第34张图片
根据漏洞原理分析,漏洞原因是因为 Srv2DecompressData函数对报文字段缺乏合法性判断造成内存分配不当。
从源码中可得,OriginalSize+ Offset = 0xffffffff + 0×10 = 0xf,其将会被传递给SrvNetAllocateBuffer进行调用来进行buffer申请:
查看SrvNetAllocateBuffer反编译代码
SMBGhost漏洞(CVE2020-0796)简单分析_第35张图片
 
SrvNetBufferLookasides表通过函数SrvNetCreateBuffer初始化,实际SrvNetCreateBuffer循环调用了SrvNetBufferLookasideAllocate分配内存, 调用SrvNetBufferLookasideAllocate的参数分别为[‘0x1100’, ‘0x2100’, ‘0x4100’, ‘0x8100’, ‘0x10100’, ‘0x20100’, ‘0x40100’, ‘0x80100’, ‘0x100100’]。在这里,内存分配参数为0xf,对应的lookaside表为0×1100大小的表项。
SMBGhost漏洞(CVE2020-0796)简单分析_第36张图片
 
而 SrvNetBufferLookasideAllocate函数调用SrvNetAllocateBufferFromPool来进行内存分配,而其内部又是通过ExAllocatePoolWithTag函数进行分配,返回值指向内存分配地址。
SMBGhost漏洞(CVE2020-0796)简单分析_第37张图片
内存分配完毕后,SrvNetAllocateBufferFromPool函数还对分配的内存进行一系列初始化操作,最后返回一个内存信息结构体指针。
总结内存布局如下图:
SMBGhost漏洞(CVE2020-0796)简单分析_第38张图片
 
当smb服务端收到压缩数据后,调用SmbCompressionDecompress函数进行解压,而该函数实质调用的是RtlDecompressBufferEx2函数。结合RtlDecompressBufferEx2函数可以分析得到SmbCompressionDecompress函数的各个参数含义是:
SmbCompressionDecompress(CompressAlgo,//压缩算法
Compressed_buf,//指向数据包中的压缩数据
Compressed_size,//数据包中压缩数据大小,计算得到
UnCompressedBuf,//解压后的数据存储地址,*(alloc_buffer+0×18)+0×10
UnCompressedSize,//压缩数据原始大小,源于数据包OriginalCompressedSegmentSize
FinalUnCompressedSize)//最终解压后数据大小
从反编译代码可以看出,函数SmbCompressionDecompress中保存解压后数据的地址为*(alloc_buffer+0×18)+0×10的位置,根据内存分配过程分析,alloc_buffer + 0×18指向了实际内存分配起始位置偏移0×50处,所以拷贝目的地址为实际内存分配起始地址偏移0×60位置处。
在解压过程中,压缩数据解压后将存储到这个地址指向的内存中。根据evilData数据的构造过程,解压后的数据为占坑数据和tokenAddr。拷贝到该处地址后,tokenAddr将覆盖原内存数据结构中alloc_buffer+0×18处的数据。也就是解压缩函数SmbCompressionDecompress返回后,alloc_buffer+0×18将指向验证程序的tokenAddr内核地址。 而SMB_payload此时指向evilData中的权限数据,offset则为0×10。因此,这个内存移动完成后,权限数据将写入tokenAddr处。这意味着,SMS Server成功修改了验证程序的权限,从而实现了验证程序的提权!
动态调试:
token修改方法:
1.手动修改token的方法:
WinDBG中的!process扩展命令会显示指定进程或者全部进程的EPROCESS块信息。
SMBGhost漏洞(CVE2020-0796)简单分析_第39张图片
其中的PROCESS ffffe08fff46d380即表示System进程的EPROCESS的内存地址是0x ffffe08fff46d380。
可使用dt _EPROCESS指令查看0x ffffe08fff46d380 地址处的EPROCESS块信息:
SMBGhost漏洞(CVE2020-0796)简单分析_第40张图片
。。。( EPROCESS是较大的结构体,我们省略了部分,重点关注0x360偏移处的这个Token结构。
SMBGhost漏洞(CVE2020-0796)简单分析_第41张图片
该结构是一个_EX_FAST_REF类型。
SMBGhost漏洞(CVE2020-0796)简单分析_第42张图片
一般会通过位与法获得最终的值:
可使用!token扩展指令查看令牌的具体结构
1: kd> !token ffffcb89`8bc07420
_TOKEN 0xffffcb898bc07420
TS Session ID: 0
User: S-1-5-18
User Groups:
00 S-1-5-32-544
    Attributes - Default Enabled Owner
01 S-1-1-0
    Attributes - Mandatory Default Enabled
02 S-1-5-11
    Attributes - Mandatory Default Enabled
03 S-1-16-16384
    Attributes - GroupIntegrity GroupIntegrityEnabled
Primary Group: S-1-5-18
Privs:
02 0x000000002 SeCreateTokenPrivilege            Attributes -
03 0x000000003 SeAssignPrimaryTokenPrivilege     Attributes -
04 0x000000004 SeLockMemoryPrivilege             Attributes - Enabled Default
05 0x000000005 SeIncreaseQuotaPrivilege          Attributes -
07 0x000000007 SeTcbPrivilege                    Attributes - Enabled Default
08 0x000000008 SeSecurityPrivilege               Attributes -
09 0x000000009 SeTakeOwnershipPrivilege          Attributes -
10 0x00000000a SeLoadDriverPrivilege             Attributes -
11 0x00000000b SeSystemProfilePrivilege          Attributes - Enabled Default
12 0x00000000c SeSystemtimePrivilege             Attributes -
13 0x00000000d SeProfileSingleProcessPrivilege   Attributes - Enabled Default
14 0x00000000e SeIncreaseBasePriorityPrivilege   Attributes - Enabled Default
15 0x00000000f SeCreatePagefilePrivilege         Attributes - Enabled Default
16 0x000000010 SeCreatePermanentPrivilege        Attributes - Enabled Default
17 0x000000011 SeBackupPrivilege                 Attributes -
18 0x000000012 SeRestorePrivilege                Attributes -
19 0x000000013 SeShutdownPrivilege               Attributes -
20 0x000000014 SeDebugPrivilege                  Attributes - Enabled Default
21 0x000000015 SeAuditPrivilege                  Attributes - Enabled Default
22 0x000000016 SeSystemEnvironmentPrivilege      Attributes -
23 0x000000017 SeChangeNotifyPrivilege           Attributes - Enabled Default
25 0x000000019 SeUndockPrivilege                 Attributes -
28 0x00000001c SeManageVolumePrivilege           Attributes -
29 0x00000001d SeImpersonatePrivilege            Attributes - Enabled Default
30 0x00000001e SeCreateGlobalPrivilege           Attributes - Enabled Default
31 0x00000001f SeTrustedCredManAccessPrivilege   Attributes -
32 0x000000020 SeRelabelPrivilege                Attributes -
33 0x000000021 SeIncreaseWorkingSetPrivilege     Attributes - Enabled Default
34 0x000000022 SeTimeZonePrivilege               Attributes - Enabled Default
35 0x000000023 SeCreateSymbolicLinkPrivilege     Attributes - Enabled Default
36 0x000000024 SeDelegateSessionUserImpersonatePrivilege  Attributes - Enabled Default
Authentication ID:         (0,3e7)
Impersonation Level:       Anonymous
TokenType:                 Primary
Source: *SYSTEM*           TokenFlags: 0x2000 ( Token in use )
Token ID: 3eb              ParentToken ID: 0
Modified ID:               (0, 3ec)
RestrictedSidCount: 0      RestrictedSids: 0x0000000000000000
OriginatingLogonSession: 0
PackageSid: (null)
CapabilityCount: 0      Capabilities: 0x0000000000000000
LowboxNumberEntry: 0x0000000000000000
Security Attributes:
Invalid AUTHZBASEP_SECURITY_ATTRIBUTES_INFORMATION with no claims
Process Token TrustLevelSid: S-1-19-1024-8192
 
也可使用dt _TOKEN查看字段定义。
SMBGhost漏洞(CVE2020-0796)简单分析_第43张图片
在尝试把替换cmd.exe进程的TOKEN指针之前,我们先执行一下whoami看看。
SMBGhost漏洞(CVE2020-0796)简单分析_第44张图片图 4
手动查看cmd.exe进程的TOKEN指针。
kd> !process 0 0 cmd.exe
PROCESS ffff980ddcba8080
SessionId: 1 Cid: 0ae8 Peb: 1265dcd000 ParentCid: 0d38
DirBase: 530d6002 ObjectTable: ffffd58733943400 HandleCount: 75.
Image: cmd.exe
然后把cmd.exe进程的TOKEN指针替换为system的TOKEN指针。
kd> eq ffff980ddcba8080+0x360 
再执行一下whoami显示,当前账户已经由admin变化为nt authority\system。 SMBGhost漏洞(CVE2020-0796)简单分析_第45张图片
 
回到提权部分的动态调试
查看memmove()函数的目的地址是否就是cve-2020-0796-local.exe进程的TOKEN指针:
SMBGhost漏洞(CVE2020-0796)简单分析_第46张图片
手动查看cve-2020-0796-LPE_x64.exe进程的TOKEN指针。
SMBGhost漏洞(CVE2020-0796)简单分析_第47张图片
可以看出memmove()函数的目的地址 ,cve-2020-0796-LPE_x64.exe的TOKEN指针存放位置 ,该地址指向 ,正好是ffffcb89`92e026b0+0x40 
SMBGhost漏洞(CVE2020-0796)简单分析_第48张图片
从_TOKEN结构体的定义中,我们了解在0x40偏移处是一个_SEP_TOKEN_PRIVILEGES的结构。
SMBGhost漏洞(CVE2020-0796)简单分析_第49张图片
执行拷贝后,进行查看:
SMBGhost漏洞(CVE2020-0796)简单分析_第50张图片
 
查看 提权进程的TOKEN中的Privileges :
SMBGhost漏洞(CVE2020-0796)简单分析_第51张图片
这16字节数据正是之前我们曾观察到的System进程的TOKEN中的Privileges的Present值。Present字段表示启用的特权,Enabled字段表示拥有的特权。这16字节数据覆盖写进程的Privileges结构之后,系统即拥有并启用了的system进程所有的特权。
在修改本进程的_SEP_TOKEN_PRIVILEGES结构之后,就已经获得system进程的特权,后续调用了inject()函数。inject()函数中通过CreateToolhelp32Snapshot()创建进程快照,使用比较进程名的方法找到"winlogon.exe"进程。然后使用VirtualAllocEx申请了一块带有可执行属性的内存(PAGE_EXECUTE_READWRITE),WriteProcessMemory把shellcode写入目标进程,CreateRemoteThread()最终完成任务。
SMBGhost漏洞(CVE2020-0796)简单分析_第52张图片
 
 
2.远控原理分析
 
 
 
 
0x03 漏洞危害

cve-2020-0796漏洞可能造成系统崩溃、拒绝服务,或者可能被用于远程代码执行。
  (1) 系统崩溃:在工业控制系统场景中多数操作站、上位机、SCADA系统运行在windows系统上,操作站崩溃会导致操作员无法与操控设备;上位机、SCADA崩溃可导致工控设备失去响应,直到被人工重启。
  (2) 远程代码执行:攻击者利用该缓冲区溢出漏洞可能导致工业控制系统数据泄露,如软件版本,系统信息、工艺参数等关键数据,也可直接获取操作权限。
 
 
 
 
0xFF 写在后面

遇到的问题:
1. https://stackoverflow.com/questions/43745499/error-symbol-file-could-not-be-found-defaulted-to-export-symbols-for-ntkrn
SMBGhost漏洞(CVE2020-0796)简单分析_第53张图片
输入kn命令查看栈回溯时,看到一条关键的:
2.每次都要重启调试,其实只要设置一次,即有一次key即可后续了。
 
参考:
https://bbs.pediy.com/thread-258551.htm
http://www.tdhxkj.com/index.php/qiyexinwenfee836fb53c1adb9ffca0f12/2020/05-12/315.html
 
待研究:
1.利用如何绕过安全机制?
2.微软的win10的堆的规则?
 
 
 
 

你可能感兴趣的:(安全分析)