Splunk Inc.

12/01/2022 | News release | Distributed by Public on 12/01/2022 15:19

From Macros to No Macros: Continuous Malware Improvements by QakBot

Share:
By Splunk Threat Research Team December 01, 2022

In 2007 we saw the initial beginnings and rise of QakBot, the same year when Windows XP and Windows Server 2003 were still the primary operating systems in the enterprise. QakBot, or QuackBot, made its presence known as a banking trojan and a loader. Over time, it continually developed and became a standard in malicious software circles. Today, we see QakBot used by a varied group of adversaries in a variety of ways, such as deploying ransomware, persistence, and stealing credentials. Before an adversary has access to an endpoint or the ability to move laterally, they have to gain initial access. That initial access vector continues to evolve and keep pace with operating systems, browsers, and antivirus vendors to ensure the deliverability of malicious payloads.

In this blog, the Splunk Threat Research Team (STRT) showcases a year's evolution of QakBot. We also dive into a recent change in tradecraft meant to evade security controls. Last, we reverse engineered the QakBot loader to showcase some of its functions.

Introduction

In February 2022 Microsoft pushed an update to disable macros by default in Office products. A huge win within the industry is to prevent the vast amount of initial access vectors into an organization. It wasn't long before adversaries began to update their tradecraft to use everything except macros. Similar to what was mentioned by Bleeping Computer in February, DarkReading mentioned in this article, the change went to HTML Applications (.hta) and was very successful. Over time, we began to hear of Mark-of-the-Web (MOTW) bypasses. Windows MOTW is a simple feature in the OS that labels items and scrutinizes them as they are downloaded. As outlined by Outflank in 2020, the role of MOTW in security measures is used by Windows SmartScreen, and Protected view sandbox in Excel and Word, to name a few. How does an adversary bypass these controls? Some downloaded files do not get scrutinized, therefore evading MOTW and allowing for process execution. One popular format that we see today includes the delivery of ISO files within an HTML file. Most containers, like ISO or VHDX, are not scrutinized by MOTW.

Want to simulate Mark of the Web Bypasses? Check out Atomic Red Team T1553.005.

Below is a timeline of changes from June to October. Proxylife monitors and tracks QakBot campaigns and daily shares the indicators for each campaign. We began looking at how QakBot operated in June, four months after Microsoft disabled macros, and we can see the pattern of using .html files with embedded zip, and img files.

The simple flow chart below shows the basic infection flow of this QakBot sample.

To follow this evolution we monitor Proxylife as well as other sources (Proxylife monitors Qakbot's evolution and shares campaign indicators).

Based on this and other sources, below is a timeline of changes from June to October captured by Proxylife updates. We began looking at how QakBot operated in June, four months after Microsoft disabled macros, and we can see the pattern of using .html files with embedded zip and img files.

Immediately following, we see that on June 13, 2022 the campaign changed to using HTML smuggling with an embedded ZIP+.LNK file. Adversaries change their tradecraft frequently when attempting to see what sticks as far as evasion goes, and this is a great view into that.

Reference tweet

Jumping forward three months, we can see the more widespread use of HTML smuggling with ZIP and ISO attachments. In this particular sample, the .LNK will execute a javascript file that loads the .cmd (batch script) to continue on.


Reference tweet

While reviewing the QakBot samples outlined above, we found a particularly distinct sample that was being utilized. Once we began digging into the HTML we noticed that it had evasive techniques built in that piqued our interest. We found that ProxyLife had shared this sample on Twitter, along with the other campaigns that utilized HTML smuggling, along with a password-protected zip that contained the ISO.


Reference tweet

What we don't see here is the functionality being used to evade controls. It's easy to say "HTML smuggling" or "ISO containers", but what is the core behavior underneath it all that is making each of these different?

  • Reverse Base64 html file (2nd stage)
  • 2nd stage contained embedded password protected zip file
  • ISO file contained within Zip, including LNK and QakBot loader

We will explore this sample and showcase everything in more detail.

HTML smuggling

This has become the de facto standard for the delivery of malicious payloads as of late. What is HTML smuggling? As defined by MITRE ATT&CK T1027.006, "HTML documents can store large binary objects known as JavaScript blobs (immutable data that represents raw bytes) that can later be constructed into file-like objects. Data may also be stored in Data URLs, which enable embedding media type or MIME files inline of HTML documents."

Below we showcase two ways to view these campaigns, one from the victim perspective and the other from within the code.

Victim Perspective

For the end user, this particular sample requires the downloading and opening of the HTML file. Once opened, the attachment.zip saves to disk, and the end user must now enter the password to decrypt the contents. Once decrypted, mount the ISO (by double-clicking) and finally click the A.LNK file.

View Within Code

(For a larger resolution of this diagram visit this link)

Stage 1 HTML

This HTML file contains a reversed base64 encoded string initialized in div id = "MS860aTc" which contains the stage 2 javascript. To be able to execute this stage 2 javascript, it creates an HTML element with the tag "embed" that will be appended to the code body of this HTML using "document.body.appendChild(element)". The width and height frame properties of the "embed" element are also hidden (value = 1) to hide the stage 2 javascript execution from the user.

Figure 1 is the screenshot of the main code of the stage 1 HTML file with annotations

Figure 1

Stage2 HTML File

The stage 2 HTML contains javascript that will decode a base64 encoded (password protected) zip file initialized in variable "gdhpoIyu". After decoding, it will try to convert the decoded base64 data into an unsigned integer byte array that will be used to create a blob file object as a ZIP file. Then it will use a javascript static method URL.CreateObjectURL with the new blob file object as a parameter that will be loaded using the windows.location.assign() method.

Figure 2 shows the stage 2 HTML javascript code and the portion of the base64 encoded zip file that contains the malicious ISO file.

Figure 2

Figure 3 shows the effect of the stage 2 HTML file as you run the main HTML (stage 1). Notice that it automatically dropped the zip file in the compromised host.

Figure 3

ISO File

Once the ZIP is extracted and decrypted using the password "PG1", we will be able to get the "A7490.iso" that contains an A.LNK file and a hidden tools folder.

Hidden Folder Contents

Within the hidden tools folder is protracted.cmd (bat file) and the malicious bucketfuls.dat (.dll) that will be loaded.

LNK and Batch Script

To the victim, the .LNK will be the only thing inside the ISO as the tools directory is hidden.

Below is the breakdown of the two files which showcases how the adversary attempts to evade detection.

LNK

Within the LNK it gives away the .cmd file that will run from within the hidden tools directory -

C:\Windows\System32\cmd.exe /c tools\protracted.cmd re gs v


Note the re gs and v arguments, at first glance it doesn't make sense and seems out of place until we look at the .cmd file.

Figure 4

The .cmd file uses a few tricks to evade controls. First, lines 4-7 are using set, which will _set_ environment variables for the different strings. On line 6 we see the % symbols, which are passed in from the LNK file (re gs v) to complete the regsvr32.exe process name.

Line 9 will set "copy" as a variable. The final call on line 16 will now look like this:

copy %systemroot%\system32\regsvr32.exe %temp%\envelopingConcussion.com

This will copy regsvr32.exe from system32 to the \appdata\local\temp directory and rename regsvr32.exe to envelopingConcussion.com.

Now, envelopingConcussion.com will run tools\bucketfuls.dat.

In Splunk:

Figure 5

Now we will switch gears and dive into the different QakBot capabilities found within the DLL that gets loaded.

System Owner/User Discovery

Figure 6 is a screenshot of QakBot code that will execute several Windows commands to collect system and network information that will be sent to the remote C2 server.

Figure 6

The table below is the complete list of the Windows commands that it will execute on the compromised host.

Table 1

Command Description

ipconfig /all

List all TCP/IP network configuration

nslookup -querytype=ALL -timeout=12 _ldap._tcp.dc._msdcs.%s

Query SRV records of the domain from the main DNS record of the compromised host (%s is the domain name)

nltest /domain_trusts /all_trusts

Enumerate domain trusts

net localgroup

Get local groups information

qwinsta

Displays information about sessions on a Remote Desktop Session Host server.

route print

Get route information

arp -a

Get ARP information

cmd /c set

Get environment variables

whoami /all

Get user, group, and privilege information of the compromised host

netstat -nao

Get the active network connections in the compromised host

net view

Displays a list of domains, computers, or resources that are being shared by the specified computer.

net share

Displays information about all of the resources that are shared on the local computer

This event can be seen using the Sysmon event logs in Splunk. Figure 7 shows how the QakBot malware injected in the wermgr.exe process executes the following Windows native commands that we've listed in the above table.

Figure 7

As part of this Tactic, it will also execute several WMI query commands to gain more system information about the compromised host. Table 2 shows the list of WMI classes it uses in its WMI query to collect more information.

Table 2

WMI Class Description

Win32_ComputerSystem

System Information (AdminPasswordStatus, Model, Name, Manufacturer and many more)

Win32_Bios

BIOS information (e.g BIOSVersion, PrimaryBIOS, serialNumber)

Win32_Product

Product and software information

Win32_PhysicalMemory

Physical RAM information

Win32_DiskDrive

Hard disk information like the partition, free size, model.

Win32_Processor

CPU processor information

Win32_OperatingSystem

OS information

SELECT * FROM antivirusProduct

List all antivirus Products Installed in Windows OS.

Additionally, it will also make Windows API calls to get the computer name, system metrics, Active Directory domain status, system info, all processes and its modules, windows architecture (x32/x64), and OS version.

Figure 8 shows a code snippet of how it gets the computer name and the volume information of the compromised host.

Figure 8

Figure 9 shows the short code snippet of how it sets up and executes the WMI command listed in the table above to perform system discovery on the compromised host.

Figure 9

Persistence

QakBot will also create a registry run key entry or Scheduled Task to execute itself upon the reboot of the compromised host. Figure 10 shows the code snippet of this sample that creates scheduled tasks or creates registry run keys.

Figure 10

We also saw a function in its code capable of creating services for its malicious code to gain privileges or persist on the target host machine. Unfortunately, this TTP was not triggered during our testing. Figure 11 is a screenshot of how it registers a service control handler for its file.

Figure 11

Execution

This QakBot sample can execute the dropped .DLL copy of itself or a .DLL plugin downloaded from its Command and Control (C2) server using several techniques available in Windows Operating System such as Living on The Land Application (LOLBIN) or through scripts.

Figure 12 shows how it uses the WMI command in .VBScript to copy files.

Figure 12

Below is a short table of commands we saw during our analysis for its Execution Tactics

Table 3

Command Description
Regsvr32.exe

Execute dropped randomly generated DLL file name using regsvr32.exe.

Rundll32.exe

Execute dropped randomly generated DLL file name using rundll32.exe.

Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\%coot\cimv2")

Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process")

errReturn = objProcess.Create("%s", null, nul, nul)

Execute a process using a WMI object in VBScript.

"runas"

Shellexecute a command line with "runas " parameter to gain admin privileges in its execution

Powershell.exe -encodedCommand

Execute a base64 encoded PowerShell script

Wmic process call create expand Execute its dropped DLL copy of itself or .dll component using WMIC in a batch script.
E.g Wmic process call creates expand regsvr32.exe

Defense Evasion, Privilege Escalation - Process Injection

When The .DLL stager or the .DLL loader is executed by the .batch script inside the .ISO file using regsvr32.exe, It will inject its malicious code to a legitimate Windows OS process to perform defense evasion.

Figure 13 shows the code and how it creates a suspended process (the wermgr.exe) as the first step of the process hollowing technique.

Figure 13

After creating a suspended process, it will create a new section on that process that can fit its QakBot .DLL code. Then, it will map and allocate memory pages on that section and write its malicious code on that mapped section using WriteProcessMemory() API. Figure 13.1 is the code snippet of this process.

Figure 13.1

Below is the list of possible processes where it can inject the QakBot core .DLL during its executions:

  • %SystemRoot%\SysWOW64\OneDriveSetup.exe
  • %SystemRoot%\SysWOW64\dxdiag.exe
  • %SystemRoot%\SysWOW64\explorer.exe
  • %SystemRoot%\SysWOW64\mobsync.exe
  • %SystemRoot%\SysWOW64\msra.exe
  • %SystemRoot%\SysWOW64\wermgr.exe
  • %SystemRoot%\SysWOW64\xwizard.exe
  • %SystemRoot%\System32\OneDriveSetup.exe
  • %SystemRoot%\System32\dxdiag.exe
  • %SystemRoot%\System32\mobsync.exe
  • %SystemRoot%\System32\msra.exe
  • %SystemRoot%\System32\wermgr.exe
  • %SystemRoot%\System32\xwizard.exe
  • %SystemRoot%\explorer.exe

Anti-Analysis and Anti-Debugging

Aside from Process Injections, it also has several functions that check if it is being debugged, being run in a sandbox, or being analyzed in a research lab.

This QakBot variant has 2 conditions that serve as a killswitch for its execution.

  1. It checks if the file "C:\INTERNAL\__empty" exists. This file can be used to check the existence of Windows Defender emulation. If this file exists it will right away return 0 that will exit its code execution.
  2. The second one is checking the environment variable "SELF_TEST_1". If this environment variable exists it will exit the process.

Figure 14 shows the screenshots of its code that checks the following killswitch

Figure 14

Figure 15 shows its code snippet and how it checks if its code is being debugged using the Process Environment Block Structure. If the BeingDebugged flag is True, it will xor encrypt the 2 decryption key tables in addresses 0x1001E16B0 and 0x1001E050 then exit its process.

Figure 15

It also enumerates all the running processes on the compromised host and checks if one of those processes is on the list below (Table 4) which is related to security, malware analysis tools, and sandbox.

Table 4

  • frida-winjector-helper-32.exe
  • frida-winjector-helper-64.exe
  • tcpdump.exe
  • windump.exe
  • ethereal.exe
  • wireshark.exe
  • ettercap.exe
  • rtsniff.exe
  • packetcapture.exe
  • capturenet.exe
  • ResourceHacker.exe
  • sniff_hit.exe
  • qak_proxy
  • dumpcap.exe
  • CFF Explorer.exe
  • not_rundll32.exe
  • ProcessHacker.exe
  • tcpview.exe
  • filemon.exe
  • procmon.exe
  • idaq64.exe
  • loaddll32.exe
  • PETools.exe
  • ImportREC.exe
  • LordPE.exe
  • SysInspector.exe
  • proc_analyzer.exe
  • sysAnalyzer.exe
  • sniff_hit.exe
  • joeboxcontrol.exe
  • joeboxserver.exe
  • x64dbg.exe
  • Fiddler.exe
  • sysAnalyzer.exe

It also has a list of processes it checks (Table 5) related to antivirus products such as AVG, Dr. Web, Fortinet, TrendMicro, F-Secure, ByteFence Anti-Malware, BitDefender, Avast, Windows Defender, Comodo Internet Security and ESET.

Table 5

  • avgcsrvx.exe
  • avgsvcx.exe
  • avgcsrva.exe
  • dwengine.exe
  • dwarkdaemon.exe
  • dwwatcher.exe
  • fmon.exe
  • coreServiceShell.exe
  • PccNTMon.exe
  • NTRTScan.exe
  • bdagent.exe
  • vsserv.exe
  • vsservppl.exe
  • AvastSvc.exe
  • mcshield.exe
  • MsMpEng.exe
  • vkise.exe
  • isesrv.exe
  • cmdagent.exe
  • egui.exe
  • ekrn.exe
  • fshoster32.exe
  • ByteFence.exe

It also checks antivirus .DLL's component if it is loaded on the compromised host. Figure 16 shows the function that checks if the Avast module (awshooka.dll and aswhookx.dll) is installed or running on the compromised host.


Figure 16

Command and Control (C2)

This malware is capable of communicating to its C2 server to send the collected data in the compromised Windows OS and also to download configuration files, plugins, or other malware.

Figure 17 shows the code snippet that contains a function renamed as "mw_internet_crack_send_request" that will send a request to its C2 using HttpSendRequestA() API. Then it will be followed by another function that will read the reply from the HTTP Request and save it to a file that could be either a configuration file or other malware to be executed in the target or compromised host.

Figure 17

This malware also uses a named pipe to communicate to its other process running on the compromised host. Figure 18 is a code snippet showing how it creates named pipes and reads data or files sent or transferred on that randomly generated named pipe.

Figure 18

Figure 19 shows how Sysmon Event=17, 18 (CreateNamedPipe And ConnectNamedPipe) captured the creation and connection of the injected QakBot in legitimate wermgr.exe process to its randomly generated named pipe.

`sysmon` EventCode IN (17, 18) Image= "*\\wermgr.exe" EventType IN ( "CreatePipe", "ConnectPipe") 
| stats  min(_time) as firstTime max(_time) as lastTime count by Image EventType ProcessGuid ProcessId PipeName SecurityID EventCode Computer UserID 
| `security_content_ctime(firstTime)` 
| `security_content_ctime(lastTime)` 

Figure 19

In addition to all this, we are also sharing the decrypted data section of this QakBot variant that contains more TTPs.

https://gist.github.com/tccontre/360dbda059562b67b983d58ae70ac371

As defenders, it doesn't end here. QakBot and other frameworks will continue to improve, evading next-generation controls in place. We must continue to dissolve these loaders into their smallest form and share with the greater security community their tradecraft to help everyone defend their organization.

Automate with Splunk SOAR Playbooks

All of the previously listed detections create entries in the risk index by default, and can be used seamlessly with risk notables and the Risk Notable Playbook Pack. The community Splunk SOAR playbooks below can be used in conjunction with some of the previously described analytics:

Playbook Description

Internal Host WinRM Investigate

This playbook performs a general investigation on key aspects of a windows device using windows remote management. Important files related to the endpoint are generated, bundled into a zip, and copied to the container vault.

Block Indicators

This playbook retrieves IP addresses, domains, and file hashes, blocks them on various services, and adds them to specific blocklists as custom lists.

Internal Host WinRM Response

This playbook accepts a list of hosts and filenames to remediate on the endpoint. If filenames are provided, the endpoints will be searched and then the user can approve deletion. Then the user is prompted to quarantine the endpoint.

Detection

Splunk Threat Research Team has curated new and old analytics and tagged them to the QakBot Analytic Story to help security analysts detect adversaries leveraging the QakBot malware. This analytic story introduces 43 detections across MITRE ATT&CK techniques.

For this release, we used and considered the relevant data endpoint telemetry sources such as:

  • Process Execution & Command Line Logging
  • Windows Security Event Id 4688, Sysmon, or any Common Information Model compliant EDR technology.
  • Windows Security Event Log
  • Windows System Event Log

Why Should You Care?

With this article the Splunk Threat Research Team (STRT) enables security analysts, blue teamers and Splunk customers to identify one of the CISA TOP malware strains . This article helps the community discover QakBot tactics, techniques and procedures. By understanding QakBot behaviors, we were able to generate telemetry and datasets to develop and test Splunk detection analytics designed to defend and respond against this threat.

Learn More

You can find the latest content about security analytic stories on GitHub and in Splunkbase. Splunk Security Essentials also has all of these detections available now.

For a full list of security content, check out the release notes on Splunk Docs.

Feedback

Any feedback or requests? Feel free to put in an issue on GitHub and we'll follow up. Alternatively, join us on the Slack channel #security-research. Follow these instructions if you need an invitation to our Splunk user groups on Slack.

Contributors

We would like to thank the authors Teoderick Contreras, Michael Haag and collaborators Lou Stella, Mauricio Velazco, Rod Soto, Jose Hernandez, Patrick Bareiss, Bhavin Patel, and Eric McGinnis for their contributions to this post.

We would like to extend a huge thank you to @proxylife for sharing his research and this malware sample that helped the STRT produce this analysis.