REvil Under the Microscope
U.S. and European law enforcement agencies revealed new seizures and arrests this week involving the REvil ransomware group, underscoring the intense interest and outrage following in the wake of these malicious campaigns. These developments also highlight the immediate need for security professionals to fully understand the inner workings of this group and the associated malware family, to better protect their organizations and stakeholders. This blog dives deep into REvil's latest tactics, techniques, and procedures (TTPs), drawing insights from a recent incident handled by the BlackBerry Incident Response Team.
Following execution of the Gootkit loader, the final deobfuscated code snippet performs the following actions:
- Loops through an array of three domains
- For each domain, generates a random string to be used as part of a download URL
- Performs an HTTP GET request to each domain, using a format string including a “search.php” endpoint, a static value (redacted here), and the randomly generated number
- Checks the GET request response for a 200 (“OK”) value
- If the GET request was successful, the downloaded content is then executed as additional code
A full analysis of the Gootkit loader and additional actions taken following its execution are included below.
Figure 2: Gootkit loader beautified code
The code kicks off with a call to summer (9754), which passes an unused integer to the summer ( ) function. This function simply calls round (9102):
After sleeping just shy of 65 seconds, the round ( ) function implements a while loop that is used to call other functions within the code. For example, when first run, the variable race is set to 5647, which is then used in a try/catch block implemented within the loop. This loop not only takes time to run, but is used to feed new values into the electric array in order to execute the next function:
Figure 4: Gootkit loader round function
In the first invocation of round, the electric [ ] array is checked to see if the current value of the array position (the value in race) equals a valid function to run. If not, the catch statement kicks in and sets a much larger integer position in the electric array to equal another function: indicate. This means that the loop will execute 2842404 - 5647 = 2,836,757 times before eventually calling the indicate ( ) function, which looks like this:
Figure 5: Gootkit loader indicate function
Notice the setting of electric  = third, which sets the next function to run after returning to the calling while loop. In this fashion, we find multiple assignments of functions to various array positions within the electric [ ] array. After another attempted sleep (commented out above), the indicate function sets the knew variable, which is later decoded.
To avoid the consistent iterations of the while loop and speed up analysis, the round ( ) function can be modified to make its calls directly, rather than waiting for the loop to continue incrementing the race value as such:
Figure 6: Gootkit loader modified round function
Decoding of the knew variable occurs within the third function called from this location, which is million ( ):
The play ( ) function is called with two arguments: The return value of a call to multiply (knew), along with a static string labeled above, as seen in Figure 7. Once this returns, the stead value is an array that includes the string “constructor” at index 0 and the following code (already beautified for review purposes) at index 1:
Figure 8: Gootkit loader stead array
Above we can see an important host-based Indicator of Compromise (IoC) for the loader, a registry key:
If this key does not exist, it is created. Next, we see another set of obfuscated code that is decoded via a call to multiply ( ). By setting a breakpoint on the return for the multiply ( ) function, we see the final bit of deobfuscated code:
Figure 9: Gootkit loader deobfuscated code
BloodHound and Kerberoasting
Following the Gootkit installation, REvil didn’t immediately make use of the persistent access to this system. Instead, the group waited three days before connecting and beginning the initial enumeration. The first hands-on-keyboard activity related to the threat actor was a BloodHound output file within the infected user’s profile directory, named <date_time>_BloodHound [.] zip, where <date_time> was the time the data was captured.
BlackBerry researchers retrieved a copy of the BloodHound output file and began enumerating attack paths that the threat actor may have abused. A path to Domain Admin was found via three “Kerberoastable” accounts. The attack paths looked similar to the following:
The REvil group used their apparent knowledge of this attack path to Kerberoast three of the accounts to retrieve their plain text credentials. Windows Event logs were unavailable during the timeframe of the incident to allow for identification of the Kerberoasting activity, although the REvil group left a text file on disk containing the Kerberos Ticket Granting Service (TGS) tickets for the three accounts assigned Service Principal Names (SPNs). The contents of the file looked similar to the following:
Figure 11: Kerberos TGS ticket
BlackBerry determined that the TGS tickets could easily be cracked using
the password cracking software tool John the Ripper
to retrieve the plain text password. These accounts were later used by the threat actor to move laterally and install additional persistence mechanisms.
Figure 12: TGS ticket cracking
Lateral Movement and Enumeration
After gaining access to multiple highly privileged accounts, the threat actor began pivoting to other hosts on the network via Remote Desktop Protocol (RDP). From there, the PsExec tool was also used to pivot to other hosts to shut down Windows Defender services.
BlackBerry also discovered the Mimikatz utility used to “pass the hash” for additional compromised accounts. This method was used to gain an RDP session on remote hosts using the NTLM hash of the compromised user account(s). While Windows does not traditionally use NTLM hashes for RDP authentication, the “restrictedadmin” argument forces RDP to pre-authenticate with an NTLM hash, presenting a pass-the-hash vulnerability.
Prior to executing the RDP pass the hash technique, the threat actor staged the remote system by enabling the restrictedadmin feature via a registry edit through PsExec.
Lastly, the Advanced IP Scanner utility was executed on multiple systems to map out network systems that the actor had access to. The Advanced IP Scanner utility is frequently abused by ransomware groups and can provide a good indicator of compromise if the tool is not used legitimately within an environment.
The threat actor utilized two methods of installing Cobalt Strike command-and-control (C2) within memory. The first and simplest method was utilizing a simple encoded PowerShell command to execute a Cobalt Strike stager. Below is a snippet from the discovered Cobalt Strike stager:
Figure 13: Encoded Cobalt Strike stager
A memory image was taken for further identification of injected processes. Using the volatility “malfind” function, BlackBerry determined that two separate “rundll32.exe” processes contained injected Windows PE files, as seen in the images below.
BlackBerry extracted the two executable files and determined that they were Cobalt Strike Beacons, configured to reach out to the following two IPs:
Command-and-Control – Registry Cradle
The BlackBerry Incident Response Team also discovered a PowerShell command used to stage Cobalt Strike within the registry key: HKLM:\SOFTWARE\Microsoft\PowerShell\info. The threat actor ran the PowerShell via a remote service which executed the following:
BlackBerry was able to retrieve a portion of the PS1 script that was executed via WMI using PowerShell script block log 4104, as shown in the following screenshot:
Figure 16: Encoded PowerShell script
The contents of the registry key were extracted for further analysis. Unfortunately, the PowerShell code executed on the system contained undefined variables, such as pdqnas. As such, it did not appear to be decodable as-is.
The REvil group is known to exfiltrate data prior to deploying ransomware. In identifying any potential exfiltration activity, the BlackBerry Incident Response Team searched across a number of forensic artifacts to identify common exfiltration tools, or enumeration of sensitive folders or file shares. The threat actor used the PowerSploit PowerShell module to discover file servers on the network that may contain sensitive data for exfiltration:
After discovering potential file servers, typically a threat actor will begin enumerating available shares. One of the most helpful artifacts in identifying enumeration of sensitive file shares or folders is the Windows Shellbag artifact, located within the USRCLASS.dat registry hive. In this case, the actor navigated through many folders on the primary file server, likely in attempts to identify the “crown jewels.”
In addition to this enumeration activity, the FreeFileSync utility was executed from the same system immediately following the Shellbag enumeration event. Unfortunately, the threat actor had deleted the folder containing any logs related to FreeFileSync, and Windows Event logs on the system were unavailable from the timeframe of the file’s initial execution. However, through file carving and memory analysis, BlackBerry was able to extract many (but not all) Windows Event logs from the incident timeframe. Windows Event ID 5156, used to track connections allowed by the Windows Filtering Platform, showed connections from FreeFileSync to Google-owned IP addresses, such as that shown in the image below.
Figure 17: FreeFileSync remote connections
Analysis of firewall activity from the system to the Google-owned IPs also revealed several gigabytes worth of network traffic sent from FreeFileSync. BlackBerry determined that the REvil group likely used FreeFileSync to exfiltrate data to Google Drive™.
Prior to deploying ransomware across the environment, the threat actor once again attempted to disable the Windows Defender feature via Powershell and Scheduled Tasks. Rather than deploying ransomware across the entire environment, the group was more selective, instead targeting the Hyper-V hosts, and more specifically the Cluster Shared Volumes (CSVs) containing the virtual machines (VMs). VMs and Hyper-V services were stopped via PowerShell just prior to deploying ransomware to the CSVs.
The file xyz[.]dll was then downloaded to the affected systems and deployed against the Cluster Shared Volumes.
REvil/Sodinokibi ransomware includes a configuration that is used to determine parameters, such as which file extensions to target for encryption, which processes to kill prior to beginning the encryption routine, and which directories or extensions to exclude to avoid causing damage to the target operating system. The Sodinokibi ransomware is well-documented in the following article by the BlackBerry Threat Research team:
Applying defense in depth is important to both detecting and preventing this sort of intrusion. BlackBerry identified several opportunities at which the threat group may have been detected and eradicated early on in the attack chain. While intrusion prevention is critical, a robust intrusion detection posture is as — if not more — vital to preventing this sort of widespread ransomware event. With 24x7x365 monitoring of antivirus/EDR tools, as well as endpoint event logs and network appliances, this event very likely could have been detected and prevented before becoming a large-scale compromise.
In this incident, BlackBerry identified multiple TTPs that can be monitored for abuse detection, including:
- Monitoring of encoded PowerShell commands or potential web requests
- Monitoring for creation of BloodHound output files
- Baseline data transfer tools and remote administration tools, such as FreeFileSync or PsExec, and monitor for outlying software
- Monitoring for usage of common password dumping techniques, such as mimikatz, procdump, or comsvcs.dll
- Monitoring for usage of enumeration tools, such as Advanced IP Scanner or PowerSploit commands