Get a demo
Voyager18 (research)

The SMBleed Vulnerability and How to Fix It with KB4560960

Derek Hays | June 11, 2020

SMBleed (CVE-2020-1206), its relation to SMBGhost and how to fix them

The SMBleed vulnerability (CVE-2020-1206) allows an attacker to read uninitialized kernel memory. It happens in the same function as SMBGhost (CVE-2020-0796), a bug in the compression mechanism of SMBv3.1.1, as explained in a previous blog.

So First – How Can You Fix It?

There are several ways to mitigate the risk from the SMBleed vulnerability.

1. Windows Update

The most recommended solution is to apply Windows updates:

Windows Version KB
Windows 10 Version 1903 KB4560960
Windows 10 Version 1909 KB4560960
Windows 10 Version 2004 KB4557957

 

Mitigation through workarounds

However, we realize that applying an update is not always an option. This is why we’ve attached several workarounds, which could help mitigate the risk immediately.

2.  Disabling SMB 3.1.1 compression

You can disable compression to block unauthenticated attackers from exploiting the vulnerability against an SMBv3 Server with the following PowerShell command:

Set-ItemProperty -Path “HKLM:SYSTEMCurrentControlSetServicesLanmanServerParameters” DisableCompression -Type DWORD -Value 1 -Force

Notes:

  1. No reboot is needed after making the change.
  2. This workaround does not prevent exploitation of SMB clients; please see item 2 under FAQ to protect clients.
  3. SMB Compression is not yet used by Windows or Windows Server, and disabling SMB Compression has no negative performance impact.

You can disable the workaround with the following PowerShell command:

Set-ItemProperty -Path “HKLM:SYSTEMCurrentControlSetServicesLanmanServerParameters” DisableCompression -Type DWORD -Value 0 –Force 

smb

3. Block TCP port 445 at the enterprise perimeter firewall

TCP port 445 is used to initiate a connection with the affected component. Blocking this port at the network perimeter firewall will help protect systems that are behind that firewall from attempts to exploit this vulnerability. This can help protect networks from attacks that originate outside the enterprise perimeter. Blocking the affected ports at the enterprise perimeter is the best defense to help avoid Internet-based attacks. However, systems could still be vulnerable to attacks from within their enterprise perimeter.

4. Blocking port 445 inside the enterprise where not needed

Where it is not needed, block port 445 on the relevant assets. This will stop lateral movements using these vulnerabilities.

Root cause

The SMBleed vulnerability happens in the Srv2DecompressData function in the srv2.sys SMB server driver, similarly to SMBGhost. It receives the compressed message sent by the client, allocates the required amount of memory, and decompresses the data.

Then, if the Offset field isn’t zero, the Srv2DecompressData function will take the data placed before the compressed data and copy it, as is, to the beginning of the allocated buffer. See appendix for a simplified version of the function.

Exploiting the bug

“The message structure contains fields such as the amount of bytes to write and flags, followed by a variable-length buffer” said the ZecOps researchers. “That’s perfect for exploiting the bug since we can craft a message such that we specify the header, but the variable-length buffer contains uninitialized data.”

As Microsoft mentioned in its advisory, “An attacker who successfully exploited the vulnerability could obtain information to further compromise the user’s system. To exploit the vulnerability against a server, an unauthenticated attacker could send a specially crafted packet to a targeted SMBv3 server. To exploit the vulnerability against a client, an unauthenticated attacker would need to configure a malicious SMBv3 server and convince a user to connect to it.”

smbleed-2
Source: https://blog.zecops.com/vulnerabilities/smbleedingghost-writeup-chaining-smbleed-cve-2020-1206-with-smbghost/

In case of a successful decompression, FinalCompressedSize is updated to hold the value of CompressedBufferSize, which is the size of the buffer. Not only this seemingly unnecessary, deliberate update of the FinalCompressedSize value made the exploitation of SMBGhost easier, it also allowed the SMBleed bug to exist.

Basic exploitation POC

Note that ZECOPS POC requires credentials and a writable share, which are available in many scenarios, but the bug applies to every message, so it can potentially be exploited without authentication. Also note that the leaked memory is from previous allocations in the NonPagedPoolNx pool, and since theycontrol the allocation size, they might be able to control the data that is being leaked to some degree.

See SMBleed POC Source Code

SMBleed1
Source: https://github.com/ZecOps/CVE-2020-1206-POC/blob/smbleed/demo.gif

SMBleedingGhost? The connection between SMBleed with SMBGhost for pre-auth RCE

Exploiting the SMBleed vulnerability without authentication is less straightforward, but still executable. ZecOps were able to combine it with the SMBGhost vulnerability for successful RCE (Remote Code Execution).

See POC demonstrating SMBGhost + SMBleed RCE POC Source Code

SMBleed2

Source: https://github.com/ZecOps/CVE-2020-0796-RCE-POC/blob/master/demo.gif

Affected Versions:

Windows 10 versions 1903, 1909, 2004

Sources:

 

 

Appendix:

Below is a simplified version of the function:

ypedef 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;

Source: https://blog.zecops.com/vulnerabilities/smbleedingghost-writeup-chaining-smbleed-cve-2020-1206-with-smbghost/

 

 

Free for risk owners

Set up in minutes to aggregate and prioritize cyber risk across all your assets and attack vectors.

"Idea for an overwhelmed secops/security team".

Name Namerson
Head of Cyber Security Strategy

strip-img-2.png

Get rid of silos;

Start owning exposure risk

Test drive the leader in exposure risk management