This blog post was authored by Hasherezade and Jérôme Segura

On November 23, we received an alert from a partner about a resurgence of Gootkit infections in Germany. Gootkit is a very capable banking Trojan that has been around since 2014 and possesses a number of functionalities such as keystroke or video recording designed to steal financially-related information.

In this latest campaign, threat actors are relying on compromised websites to socially engineer users by using a decoy forum template instructing them to download a malicious file.

While analyzing the complex malware loader we made a surprising discovery. Victims receive Gootkit itself or, in some cases, the REvil (Sodinokibi) ransomware. The decision to serve one or the other payload happens after a check with the criminal infrastructure.

Gootkit attacks observed in Germany

Security researcher TheAnalyst was the first to publicly identify an active campaign in November using a sophisticated loader that was eventually attributed to Gootkit, a banking Trojan not observed in the wild for some time. Germany’s Computer Emergency Response Team CERT-Bund later confirmed that German users were being targeted via compromised websites.

Around the same time, we started receiving reports from some of our partners and their ISPs about Gootkit-related traffic. We were able to confirm Gootkit detections within our telemetry that were all located in Germany.

Figure 1: Gootkit infections in Germany in the wake of the campaign

After a couple of days, we remediated over 600 unique machines that had been compromised.

Fake forum template on hacked websites

The initial loader is spread via hacked websites using an interesting search engine optimization (SEO) technique to customize a fake template that tries to trick users to download a file.

The template mimics a forum thread where a user asks in German for help about a specific topic and receives an answer which appears to be exactly what they were looking for. It’s worth noting that the hacked sites hosting this template are not German (only the template is); they simply happen to be vulnerable and are used as part of the threat actor’s infrastructure.

Figure 2: Compromised site loads decoy template to trick victims

This fake forum posting is conditionally and dynamically created if the correct victim browses the compromised website. A script removes the legitimate webpage content from the DOM and adds its own content (the template showing a link to a file to download).

Figure 3: A view of the HTML code behind the decoy template

There is a server-side check prior to each visit to the page to determine if the user has already been served the fake template or not, in which case the webserver will return legitimate content instead.

Fileless execution and module installation

The infection process starts once the victim executes a malicious script inside the zip archive they just downloaded.

Figure 4: Malicious script, heavily obfuscated

This script is the first of several stages that leads to the execution of the final payload. The following diagram shows a high level overview:

Figure 5: Infection flow

Stage 1 – The first JavaScript

The first JavaScript is the module that has to be manually executed by the victim, and it has been obfuscated in order to hide its real intentions. The obfuscation consists of three layers where one decodes content for the next.

The first stage (a version with cleaned formatting available here) decodes the next element:

Figure 6: First stage script

The decoded output is a comma-separated array of JavaScript blocks:

Figure 7: Decoded comma-separated array of scripts

There are four elements in the array that are referenced by their indexes. For example, the element with the index 0 means “constructor”, 1 is another block of JavaScript code, 2 is empty, 3 is a wrapper that causes a call to a supplied code.

Block 1 is responsible for reading/writing registry keys under “HKEY_CURRENT_USER\SOFTWARE\<script-specific name>”. It also deobfuscates and runs another block of code:

Figure 8: Third JavaScript layer

This fragment of code is responsible for connecting to the C2. It fetches the domains from the list, and tries them one by one. If it gets a response, it runs it further.

The above downloader script is the first stage of the loading process. Functionality-wise it is almost identical in all the dropped files. The differentiation between the variants starts in the next part, which is another JavaScript fetched from the C2 server.

Stage 2 – The second JavaScript (downloaded from the C2)

The expected response from the server is a decimal string, containing a pseudorandom marker used for validation. It needs to be removed before further processing. The marker consists of “@[request argument]@”.

Figure 9: GET request with C2 server

After conversion to ASCII, the next JavaScript is revealed, and the code is executed. This JavaScript comes with an embedded PE payload which may be either a loader for Gootkit, or for the REvil ransomware. There are also some differences in the algorithm used to deobfuscate it.

Example for the Gootkit variant (commented, full)

Figure 10: The downloaded JavaScript

The downloaded code chunk is responsible for installing the persistent elements. It also runs a Powershell script that reads the storage, decodes it and runs it further.

Stage 3 – The stored payload and the decoding Powershell

The authors diversified the method of encoding and storing the payload. During our tests we observed two ways of encoding. In one of them, the PE is stored as a Base64 encoded string, and in the other as a hexadecimal string, obfuscated by having certain numbers substituted by a pattern.

The payload is usually stored as a list of registry keys, yet we also observed a variant in which similar content was written into a TXT file.

Example of the payload stored in a file:

Figure 11: Payload as a file on disk

The content of the file is an obfuscated Powershell script that runs another Base64 obfuscated layer that finally decodes the .NET payload.

Example of the Powershell script that runs to deobfuscate the file:

"C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy Bypass -windowstyle hidden -Command "IEX (([System.IO.File]::ReadAllText('C:\Users\[username]\bkquwxd.txt')).Replace('~',''));"

Below we will study two examples of the loader: One that leads to execution of the REvil ransomware, and another that leads to the execution of Gootkit.

Example 1—Loading REvil ransomware

The example below shows the variant in which a PE file was encoded as an obfuscated hexadecimal string. In the analyzed case, the whole flow led to execution of REvil ransomware. The sandbox analysis presenting this case is available here.

Execution of the second stage JavaScript leads to the payload being written to the registry, as a list of keys. The content is encoded as hexadecimal, and mildly obfuscated.

Figure 12: Fragment of the payload stored in the registry, encoded as a hexadecimal string obfuscated with a pattern

After writing the keys, the JavaScript deploys a PowerShell command that is responsible for decoding and running the stored content.

Figure 13: The JS component deploys PowerShell with a Base64 encoded script

Decoded content of the script:

Figure 14: Decoded content

It reads the content from the registry keys and deobfuscates it by substituting patterns. In the given example, the pattern “!@#” in the hexadecimal string was substituted by “1000”, then the PE was decoded and loaded with the help of .NET Reflection.

The next stage PE file (.NET):

The .NET loader comes with a hardcoded string that is the next stage PE: the final malicious payload. The Setup function called by the PowerShell script is responsible for decoding and running the next PE:

Figure 15: Hardcoded string (PE)
Figure 16: Deploying the payload

The loader runs to the next stage with the help of Process Hollowing – one of the classic methods of PE injection.

Figure 17: REvil ransom note

Example 2 – Loading Gootkit

In an other common variant, the payload is saved as Base64. The registry keys compose a PowerShell script in the following format:

$Command =[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String("[content]")); Invoke-Expression $Command;Start-Sleep -s 22222;
Figure 18: Registry key storing payload

After decoding the base64-encoded content, we get another PowerShell script:

Figure 19: More PowerShell

It comes with yet another Base64-encoded piece that is further decompressed and loaded with the help of Reflection Assembly. It is the .NET binary, similar to the previous one.

The script calls a function “Install1” from the .NET module. This function loads another PE, that is embedded inside as a base64 encoded buffer:

Figure 20: Another buffer
Figure 21: Deploying the payload

This time the loader uses another method of PE injection, manual loading into the parent process.

The revealed payload is a Gootkit first stage binary: 60aef1b657e6c701f88fc1af6f56f93727a8f4af2d1001ddfa23e016258e333f. This PE is written in Delphi. In its resources we can find another PE (327916a876fa7541f8a1aad3c2270c2aec913bc8898273d545dc37a85ef7307f ), obfuscated by XOR with a single byte. It is further loaded by the first one.

Loader like matryoshka dolls with a side of REvil

The threat actors behind this campaign are using a very clever loader that performs a number of steps to evade detection. Given that the payload is stored within the registry under a randomly-named key, many security products will not be able to detect and remove it.

However, the biggest surprise here is to see this loader serve REvil ransomware in some instances. We were able to reproduce this flow in our lab once, but most of the time we saw Gootkit.

The REvil group has very strict rules for new members who must pass the test and verify as Russian. One thing we noticed in the REvil sample we collected is that the ransom note still points to decryptor.top instead of decryptor.cc, indicating that this could be an older sample.

Banking Trojans represent a vastly different business model than ransomware. The latter has really flourished during the past few years and has earned criminals millions of dollars in part thanks to large ransom payments from high profile victims. We’ve seen banking malware (i.e. Emotet) turn into loaders for ransomware where different threat actors can specialize in what they do best. Time will tell what this return of Gootkit really means and how it might evolve.

Detection and protection

Malwarebytes prevents, detects and removes Gootkit and REvil via our different protection layers. As we collect indicators of compromise we are able to block the distribution sites so that users do not download the initial loader.

Our behavior-based anti-exploit layer also blocks the malicious loader without any signatures when the JavaScript is opened via an archiving app such as WinRar or 7-Zip.

Figure 22: Blocking on script execution

If a system is already infected with Gootkit, Malwarebytes can remediate the infection by cleaning up the registry entries where Gootkit hides:

Figure 23: Detection of payload hidden in registry

Finally, we also detect and stop the REvil (Sodinokibi) ransomware:

Figure 24: REvil ransomware blocked heuristically

Indicators of Compromise

Compromised websites downloading JavaScript loader:

docs.anscommerce[.]com
ellsweb[.]net
entrepasteles[.]supercurro.net
m-uhde[.]de
games.usc[.]edu
doedlinger-erdbau[.]at

3rd stage JavaScript C2s:

badminton-dillenburg[.]de
alona[.]org[.]cy
aperosaintmartin[.]com

Variant 1 (Gootkit):

  1. NET loader [973d0318f9d9aec575db054ac9a99d96ff34121473165b10dfba60552a8beed4]
  2. Delphi PE [60aef1b657e6c701f88fc1af6f56f93727a8f4af2d1001ddfa23e016258e333f]
  3. PE stored in resources [327916a876fa7541f8a1aad3c2270c2aec913bc8898273d545dc37a85ef7307f]

Variant 2 (REvil):

  1. NET loader [0e451125eaebac5760c2f3f24cc8112345013597fb6d1b7b1c167001b17d3f9f]
  2. Delphi PE [d0e075a9346acbeca7095df2fc5e7c28909961184078e251f737f09b8ef892b6] – the ransomware
  3. PE stored in resources [a7e363887e9a7cc7f8de630b12005813cb83d6e3fc3980f735df35dccf5a1341] – a helper component