Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2020-0796 — Technical analysis and proof-of-concept for CVE-2020-0796 (SMBGhost), an integer overflow vulnerability in SMBv3 compression leading to local privilege escalation on Windows 10/Server. | Kitploit
Tools/GitHubGitHub/datntsec/cve-2020-0796
Privilege EscalationVulnerability AnalysisExploitationBinary Exploitation
GitHubdatntsec/cve-2020-0796

CVE-2020-0796

Technical analysis and proof-of-concept for CVE-2020-0796 (SMBGhost), an integer overflow vulnerability in SMBv3 compression leading to local privilege escalation on Windows 10/Server.

View Repository
1195 years agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2020-0796


Overview:

The compression feature added to SMBv3 starting from Windows 10/Server version 1903 contains an integer overflow vulnerability confirmed by Microsoft on 12/03/2020. It allows an attacker to perform Local Privilege Escalation (LPE) and Remote Code Execution (RCE). Here we will only discuss the LPE vulnerability.

Affected versions:

  • 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)

Analysis of the SMB Decompress process:

Analyzing the file srv2.sys, it is observed that the functions related to Decompress are called as follows:``` js Srv2ReceiveHandler | | v Srv2DecompressMessageAsync | | v Srv2DecompressData -------> SrvNetAllocateBuffer | | v SmbCompressionDecompress | | v memcpy

First function `Srv2ReceiveHandler` is called to receive an smb data packet and calls a function corresponding to the `ProtocolId` protocol. If `PrococolId` = 0x424D53FC, it will call the function `Srv2DecompressMessageAsync`, which will proceed to call the function `Srv2DecompressData` to decompress the data packet. The function `Srv2DecompressData` will call the function `SrvNetAllocateBuffer` to allocate an `Alloc` used to store the data after decompression, then it calls the function `SmbCompressionDecompress` to decompress the data packet, finally it calls the function `memcpy`. Thus the entire Decompress process has the following main steps:
- 1. Allocate
- 2. Decompress
- 3. Copy

According to documentation provided by Microsoft, the `COMPRESSION_TRANSFORM_HEADER` structure is used to send and receive compressed data from client and server. It has the following structure:``` c
typedef struct _COMPRESSION_TRANSFORM_HEADER
{
   ULONG ProtocolId;
   ULONG OriginalCompressedSegmentSize;
   USHORT CompressionAlgorithm;
   USHORT Flags;
   ULONG Offset;
} ;

Here we only focus on the 2 main fields above:

  • OriginalCompressedSegmentSize is the size of the uncompressed data segment, in bytes.
  • Offset is the offset in bytes between the start of the compressed data and the end of the _COMPRESSION_TRANSFORM_HEADER structure.

Thus the compressed data packet will have the following form:

``` c 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;

}

Analysis of the `Srv2DecompressData` function reveals that it receives a compressed packet data `COMPRESSION_TRANSFORM_HEADER` (Header), allocates a memory region (Alloc) using the `SrvNetAllocateBuffer` function with the sum of `Header->OriginalCompressedSegmentSize` + `Header->Offset` as the parameter, then decompresses the compressed data and copies the uncompressed data into `Alloc->Buffer`.

![](https://assets.kitploit.com/production/public/readmes/24501/a5bf8b5059336fb3677162343bace0d0b45085f2eb89e42d85f81e032fe233dc.png)

An integer overflow error occurs when `Srv2DecompressData` calls the `SrvNetAllocateBuffer` function. The `SrvNetAllocateBuffer` function actually accepts two 64-bit values, but when calling `SrvNetAllocateBuffer`, `Srv2DecompressData` only passes two 32-bit values (ULONG) to it. Meanwhile, both `OriginalCompressedSegmentSize` and `Offset` are ULONG, and when they are added together, the result can exceed 32 bits. This causes an integer overflow (Simply put, adding 0xffffffff (`OriginalCompressedSegmentSize`) to 0x10 (`Offset`) yields 0xf0000000f but `SrvNetAllocateBuffer` only receives 0x0000000f).

![](https://assets.kitploit.com/production/public/readmes/24501/5ef540fac05ff782b005994410e1c43f18c0503fd134a57e1e6ed50c1fbc8219.png)

The integer overflow leads to incorrect allocation of the Alloc memory region (the size to be allocated is smaller than the actual required size), which can cause a buffer overflow:
![](https://assets.kitploit.com/production/public/readmes/24501/24c32abbbd764c35df1e73a00b5844711af77018cb54942a9738f5c9cac7ce4a.png)
Download Tool