It has been almost six months since an eye opening vulnerability in Microsoft Windows RDP CVE 2019-0708, dubbed BlueKeep, was patched. Today, Security Researcher Kevin Beaumont posted a Twitter thread reporting BSODs (Blue Screen of Death) across his network of BlueKeep Honeypots.
huh, the EternalPot RDP honeypots have all started BSOD'ing recently. They only expose port 3389. pic.twitter.com/VdiKoqAwkr— Kevin Beaumont (@GossiTheDog) November 2, 2019
Kevin kindly shared the crash dump with us and following this lead, we discovered the sample was being used in a mass exploitation attempt. Due to only smaller size kernel dumps being enabled, it is difficult to arrive at a definite root cause.
From initial observation, the call stack of the analysis seems off. Notably, the address
0x1aec08 is not allocated, or not present in the dump. Instead, We decided to look at pool allocations with the
TSic tag, which is the pool tag used by
termdd.sys, the Windows RDP driver.
Looking at the
TSic allocations, it’s clear something is off. Under normal circumstances there should be fewer than 100 allocations with the
TSic tag, but in this case there are over 19,000, suggesting exploitation.
In particular, the allocations of size 0x170 stand out. From previous BlueKeep research, we know the size 0x170 is the exact size of the channel structure (plus metadata). During BlueKeep exploitation, the
MS_T120 channel struct is freed, leaving a dangling pointer. To exploit the vulnerability, one must fill the memory hole with an allocation of 0x170 bytes. The thousands of allocations of 0x170 bytes suggest the exploitation technique of heap spraying, so let’s look deeper and verify.
As anticipated, the allocation is a valid channel structure for the exploitable
At offset 0x100 into the channel struct, there is an indirect pointer to a function. To gain Remote Code Execution (RCE), the attacker must hijack this pointer to lead to their shellcode, so it is crucial now to determine if it is set.
Indeed, we find it is set. If this is a BlueKeep exploit, we should find that dereferencing the address
fffffa80`08807048 will lead to the payload or exploit shellcode.
Finally, we confirm this segment points to executable shellcode. At this point we can assert valid BlueKeep exploit attempts in the wild, with shellcode that even matches that of the shellcode in the BlueKeep metasploit module!
The snippet of shellcode does a simple “egghunt” (scans the system memory for a binary signature) to find the rest of the shellcode. The “egg” is
0x0b00dac0fefe42069. By scanning the memory for this value, we’ll find the rest of the shellcode.
There are hundreds of copies of the signature in memory, which is consistent with heap spraying.
Again, the second part of the shellcode also matches that from the BlueKeep metasploit module. Seeing as most of the exploit shellcode seems to match that of metasploit, it can be assumed the usermode shellcode egg would be unchanged. Checking this we did the same memory scan but this time for the usermode egg
Not only was the egg the same, but the payload is easily visible at the end of shellcode. It’s an encoded PowerShell command.
By decoding the PowerShell command, we obtain code to download another PowerShell command from the attacker’s server.
After this, another encoded PowerShell command is downloaded. And another. Eventually we arrive at the command which downloads and executes an actual executable binary.
This binary’s hash is known to VirusTotal as a cryptocurrency miner.
It is curious that this publicly known wormable vulnerability, known to everyone who would care to know for at least six months, took this long to get detectably weaponized. One might theorize that attackers know they have essentially one shot at using it at scale, and it becomes a game of chicken as to who will do it first. It is also worth noting that mass exploitation for gain can be difficult, owing to the risks involved.
Although this alleged activity is concerning, the information security community (correctly) predicted much worse potential scenarios. Based on our data we are not seeing a spike in indiscriminate scanning on the vulnerable port like we saw when EternalBlue was wormed across the Internet in what is now known as the WannaCry attack. It seems likely that a low-level actor scanned the Internet and opportunistically infected vulnerable hosts using out-of-the-box penetration testing utilities.