Sophos has been investigating two different ransomware attacks where the adversaries deployed a legitimate, digitally signed hardware driver in order to delete security products from the targeted computers just prior to performing the destructive file encryption portion of the attack.
The signed driver, part of a now-deprecated software package published by Taiwan-based motherboard manufacturer Gigabyte, has a known vulnerability, tracked as CVE-2018-19320. The vulnerability, published along with proof-of-concept code in 2018 and widely reported at the time, was disclaimed by the company, who told the researcher who tried to report the bug that “its products are not affected by the reported vulnerabilities.” The company later recanted, and has discontinued using the vulnerable driver, but it still exists, and it apparently remains a threat.
The sha1RSA Authenticode signature for the driver, with serial number 248472542c24ab8e429229acf121ca26 and thumbprint 32daee48ae406222c2bb92c4f1b7f516e537175a, expired on October 17, 2013.
In this attack scenario, the criminals have used the Gigabyte driver as a wedge so they could load a second, unsigned driver into Windows. This second driver then goes to great lengths to kill processes and files belonging to endpoint security products, bypassing tamper protection, to enable the ransomware to attack without interference.
This is the first time we have observed ransomware shipping a trusted, signed (yet vulnerable) third party driver to patch the Windows kernel in-memory, load their own unsigned malicious driver, and take out security applications from kernel space. The ransomware that was being installed in both instances calls itself RobbinHood.
Ransomware trying to circumvent security products is not new. For example, Nemty kills processes and services using regular taskkill, and Snatch ransomware figured out how to reboot PCs into Safe Mode to get around endpoint protection. Obviously, doing the process killing from kernel mode has a lot of advantages.
This article takes a deep dive on how the attackers do it. We’re publishing this information now so other defenders can anticipate and enact defenses against this novel attack, where adversaries bring a vulnerable third party driver to subvert the Windows kernel, terminate defenses, and encrypt files unhindered by endpoint protection software.
Attacking Windows defenses
We’ve recently seen the RobbinHood ransomware family perform this strategy to encrypt files without being hindered by endpoint protection software. They successfully subvert a setting in kernel memory on Windows 7, Windows 8 and Windows 10.
Without diving into the ransomware or data encryption itself, we’re going to focus on the module with which the adversaries can kill encountered endpoint protection software. This part of the attack consists of several files embedded in STEEL.EXE. All of these files are extracted to C:\WINDOWS\TEMP
STEEL.EXE | Kill application | This is the application that kills the processes and files of security products, using kernel drivers. |
ROBNR.EXE | Driver installer | Deploys both the benign, signed third-party driver, and the criminals’ unsigned kernel driver. Once deployed, the unsigned driver gets loaded by abusing a known vulnerability in the third-party driver. |
GDRV.SYS | Vulnerable kernel driver | A benign but outdated Authenticode-signed driver that contains a vulnerability. |
RBNL.SYS | Malicious kernel driver | The malicious driver that can kill processes and delete files from kernel space. |
PLIST.TXT | List of processes (and their associated files) to destroy | This is a text file containing the names of the applications the malicious driver will kill and delete. This text file is not embedded in STEEL.EXE and may be tailored to the victim’s environment. |
STEEL.EXE
The STEEL.EXE application kills the processes and deletes the files of security applications. In order to do this, STEEL.EXE deploys a driver. The driver runs in kernel mode and is therefore optimally positioned to take out processes and files without being hindered by security controls like endpoint protection. Even though they run under NT AUTHORITY/SYSTEM, most parts of an endpoint security product run in user space.
The STEEL.EXE application first deploys ROBNR.EXE, which installs the malicious unsigned driver RBNL.SYS.
Once this driver is installed, STEEL.EXE reads the PLIST.TXT file and instructs the driver to delete any application listed in PLIST.TXT, then killing their associated processes. If the process was running as a service, the service can no longer automatically restart as the associated file has been deleted.
Once the STEEL.EXE process exits, the ransomware program can perform its encryption attack without being hindered by the security applications that have been taken out decisively.
ROBNR.EXE
This application is dropped to the disk by STEEL.EXE. This is a convenient application that drops and installs both the vulnerable GDRV.SYS driver, and the malicious RBNL.SYS driver.
64-bit Windows computers have a mechanism called driver signature enforcement which means that Windows only allows drivers to be loaded that have been properly signed by both the manufacturer and Microsoft. This is a requirement for all drivers in order to be loaded on 64-bit versions of Windows.
The malware authors did not bother to sign their malicious driver as it involves purchasing a certificate. Also, a purchased certificate can be revoked by the certificate authority causing the driver to no longer work, as it will no longer be accepted by Windows.
Instead, the malware authors chose a different route. The properly signed third party GDRV.SYS driver contains a privilege escalation vulnerability as it allows reading and writing of arbitrary memory. The malware authors abuse this vulnerability in order to (temporarily) disable driver signature enforcement in Windows – on-the-fly, in kernel memory. Once driver signature enforcement is disabled, the attackers are able to load their unsigned malicious driver.
Disabling Driver Signature Enforcement
The attackers are able to disable driver signature enforcement by changing a single variable (a single byte) that lives in kernel space. On Windows 7 (or older), this variable is called nt!g_CiEnabled (NTOSKRNL.EXE). On Windows 8 and 10, this variable is called ci!g_CiOptions (CI.DLL). In order to resolve the location of this variable, the attackers use a strategy taken from DSEFix.
On Windows 8 or 10, the trick starts by loading the standard Windows component CI.DLL as a data library using DONT_RESOLVE_DLL_REFERENCES in their process. Once CI.DLL is loaded, they query the location of CI.DLL in kernel memory via the GetModuleBaseByName function. It uses NtQuerySystemInformation(SystemModuleInformation …) to get the kernel addresses of all loaded kernel modules.
Once they know those kernel addresses, the attackers resolve the exported CiInitialize function from the module’s export address table.Then they disassemble the instructions of that function in order to find the call CipInitialize() instruction. Once that function is found, they look for the mov dword ptr [address],ecx instruction. That address is g_CiOptions as shown in the figure below.
Now that they know the location of the g_CiOptions variable in kernel space, the vulnerable third party driver is dropped to disk and started. See this article on the exact vulnerability. Any vulnerable driver that allows arbitrary read/write in kernel will do. So even though the attackers are using the GDRV.SYS driver to do this today, there’s no reason they will continue to use it if it becomes untenable to do so.
There are many other vulnerable drivers (with a similar vulnerability) in addition to the Gigabyte driver that these or other attackers may choose to abuse later, such as ones from VirtualBox (CVE-2008-3431), Novell (CVE-2013-3956), CPU-Z (CVE-2017-15302), or ASUS (CVE-2018-18537). But in these attacks, we’ve only seen the Gigabyte driver being abused in this way.
The malicious driver
Once the malicious driver is successfully deployed and started, the ROBNR.EXE process exits. Then STEEL.EXE starts processing the PLIST.TXT file, listing all the applications to kill.
This malicious kernel driver is used to terminate processes and delete the associated files. It employs several tricks to kill these applications, even when they are in-use and protected by tamper protection mechanisms employed by security products.
The following string was found in the malicious driver, indicating it was likely built by the same authors behind the RobbinHood ransomware.
C:\Users\Mikhail\Desktop\Robnhold\x64\Win7Release\Robbnhold.pdb
Deleting Files
The malicious driver has various ways to delete files. But it does not pick one way, it runs them all sequentially, in order to ensure the file really gets deleted.
To delete files that are in-use the malicious driver issues an I/O Request Packet (or IRP, a low-level message passed between device drivers) directly on the NTFS.SYS storage device. By clearing the ImageSectionObject and DataSectionObject pointers, the storage device assumes the files are not in-use and the file is safely deleted, even when the file is still running as a process!
This trick is similar to the technique mentioned on this blog post.
Terminating Processes
Once the files are deleted, STEEL.EXE kills all the processes associated with the files. Again, it uses its malicious kernel driver to terminate the processes.
Endpoint protection processes that rely on object handle filtering for their tamper protection cannot prevent a kernel mode termination of processes or deletion of files. The process handles opened by the malicious driver are kernel handles, and kernel handles cannot be filtered. So, the malicious kernel driver can kill these processes without interference of endpoint security controls. One solution is for the endpoint protection process to watch for any process trying to install these vulnerable kernel mode drivers, and prevent the installation from taking place.
If the process was running as a service, the Service Control Manager of Windows will (usually) try to restart the process that just got killed. But it will fail to do so as the related file no longer exists. Consequently, the application is effectively and permanently disabled. The failed attempts to restart the service show up in Event Logs.
When STEEL.EXE has killed all the processes and files in the PLIST.TXT list, it exits. Now the ransomware can encrypt all the files on the system unhindered.
What users can do to prevent this type of attack
Computers that are fully patched and have no known vulnerabilities can still end up in ruin because this attacker brings his own vulnerability. So what can you do to prevent the initial access by the attacker?
Adopt a three-pronged approach to minimize your risk of falling victim to an attack.
1. Threat protection that disrupts the whole attack chain
Today’s ransomware attacks use multiple techniques and tactics, so focusing your defense on a single technology leaves you very vulnerable.
Instead, deploy a range of technologies to disrupt as many stages in the attack as possible. And integrate the public cloud into your security strategy.
2. Strong security practices
These include:
- Use multi-factor authentication (MFA)
- Use complex passwords, managed through a password manager
- Limit access rights; give user accounts and admins only the access rights they need
- Make regular backups, and keep them offsite and offline where attackers can’t find them
- Lock down your RDP; turn it off if you don’t need it, use rate limiting, 2FA or a VPN if you do
- Ensure tamper protection is enabled – other ransomware strains attempt to disable your endpoint protection, and tamper protection is designed to prevent this from happening
3. Ongoing staff education
People are invariably the weakest link in cybersecurity, and cybercriminals are experts at exploiting normal human behaviors for nefarious gain. Invest – and keep investing – in staff training.
IoCs
We analyzed the following files in the course of this investigation
SHA256 | Filename |
791c32a95f401f7464214960e49e716656f6fd6fff135ac2a6ba607236d3346e | STEEL.EXE |
99c3cc348f8ee4e87bce45b1dd185d31830c370ac43fd3e39ac50340f029ef79 | ROBNR.EXE |
0b15b5cc64caf0c6ad9bd759eb35383b1f718edf3d7ab4cd912d0d8c1826edf8 | RBNL.SYS |
31f4cfb4c71da44120752721103a16512444c13c2ac2d857a7e6f13cb679b427 | GDRV.SYS |
Acknowledgments
SophosLabs would like to acknowledge the contributions of Anand Ajjan, Richard Cohen, Sivagnanam Gn, Roland Gyorffi, Erik Loman, Peter Mackenzie, Vikas Singh, Gabor Szappanos, Alex Vermaning and Michael Wood to the analysis for this post.