# QakBot reducing its on disk artifacts **[hornetsecurity.com/en/threat-research/qakbot-reducing-its-on-disk-artifacts/](https://www.hornetsecurity.com/en/threat-research/qakbot-reducing-its-on-disk-artifacts/)** Security Lab December 15, 2020 ## Summary QakBot has been updated with more evasion techniques. QakBot’s configuration is now stored in a registry key instead of a file. The run key for persistence is not permanently present in the registry but only written right before shutdown or reboot, and deleted immediately after QakBot is executed again. QakBot’s executable is also not stored permanently on the file system anymore, but similarly to the run key registry entry, dropped onto the file system before reboots and deleted afterwards. This way security software can only detect QakBot artifacts on disk, right before system shutdown, and shortly after system boot. However, at that time security software itself is shutting down and booting up, hence may not detect QakBot’s new persistence method. Other changes include dynamic just-in-time decoding and destruction of strings at runtime. So any string used in the malware is only decoded at runtime into memory only and destroyed right afterwards. The delivery method for the observed QakBot campaigns identified via the regular expression pattern of `abc[0-9]+ is still XLM macro documents as reported previously.` ## Background QakBot (also known as QBot, QuakBot, Pinkslipbot) has been around since 2008. It is distributed via Emotet, i.e., Emotet will download QakBot onto victims that are already infected with Emotet but it is also distributed directly via email. To this end, it uses email conversation thread hijacking in its campaigns,1 i.e., it will reply to emails that it finds in its victim’s mailboxes. QakBot is known to escalate intrusions by downloading the ProLock ransomware2 or lately the Egregor ransomware. The observed QakBot campaigns identified by campaign ID `abc use XLM macro` documents for infection. We previously reported on their low detection.3 An overview of the current chain of infection used by the QakBot campaign with identifiers following the regular expression pattern of `abc[0-9]+ can be seen in the following flow` graph. ----- ## Technical Analysis In the following analysis we briefly analyze the infection chain of QakBot after being downloaded and launched by the malicious Excel document. ----- ### Evasion QakBot uses various evasion techniques to avoid detection by anti-virus software. **PE header manipulation** We observed some QakBot DLLs with a manipulated PE header. The message text `This` ``` program cannot be run in DOS mode. has been altered. ``` This seems like an attempt to circumvent some static detection rules matching for this message in the legacy MS-DOS stub of PE binaries. ----- **Code signing** First, the initial downloaded and executed DLL is signed with a (at the time the analyzed sample was distributed) valid code signing certificate. ``` $ chktrust 904400.jpg Mono CheckTrust - version 6.8.0.123 Verify if an PE executable has a valid Authenticode(tm) signature Copyright 2002, 2003 Motus Technologies. Copyright 2004-2008 Novell. BSD licensed. WARNING! 904400.jpg is not timestamped! SUCCESS: 904400.jpg signature is valid and can be traced back to a trusted root! ``` The signing CA is Sectigo and the organization is given as Aqua Direct s.r.o., which is an existing company. ----- ``` $ osslsigncode verify 904400.jpg Current PE checksum : 00091021 Calculated PE checksum: 00091021 Message digest algorithm : SHA1 Current message digest : 632DCB214EE9FB08441C640D240F672A7ABA6EB1 Calculated message digest : 632DCB214EE9FB08441C640D240F672A7ABA6EB1 Signature verification: ok Number of signers: 1 Signer #0: Subject: /C=CZ/postalCode=619 00/L=Brno/street=\xC5\xBDelezn\xC3\xA1 646/8/O=Aqua Direct s.r.o./CN=Aqua Direct s.r.o. Issuer : /C=GB/ST=Greater Manchester/L=Salford/O=Sectigo Limited/CN=Sectigo RSA Code Signing CA Number of certificates: 4 Cert #0: Subject: /C=CZ/postalCode=619 00/L=Brno/street=\xC5\xBDelezn\xC3\xA1 646/8/O=Aqua Direct s.r.o./CN=Aqua Direct s.r.o. Issuer : /C=GB/ST=Greater Manchester/L=Salford/O=Sectigo Limited/CN=Sectigo RSA Code Signing CA Cert #1: Subject: /C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services Issuer : /C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services Cert #2: Subject: /C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority Issuer : /C=GB/ST=Greater Manchester/L=Salford/O=Comodo CA Limited/CN=AAA Certificate Services Cert #3: Subject: /C=GB/ST=Greater Manchester/L=Salford/O=Sectigo Limited/CN=Sectigo RSA Code Signing CA Issuer : /C=US/ST=New Jersey/L=Jersey City/O=The USERTRUST Network/CN=USERTrust RSA Certification Authority Succeeded ``` It is unknown whether the certificate was obtained from Sectigo by giving false information, the certificate was stolen from Aqua Direct s.r.o., or whether the certificate was obtained from Sectigo by giving stolen information from Aqua Direct s.r.o.. QakBot is known to steal victim emails and use them in future malspam campaigns. So it is likely that they also use stolen victim data to obtain code signing certificates. However, the actors behind QakBot can also buy the code signing certificate from a (malicious) third party. **Strings only decoded at runtime** QakBot will decode its strings only at runtime into memory. After usage the decoded strings are removed from memory again. ----- **Processes** QakBot uses `CreateToolhelp32Snapshot and` `Process32{First,Next}W to enumerate` the running processes. It checks for the following processes: ``` WRSA exe ``` ----- ``` vkise.exe ``` QakBot will set specific bits in a bit mask for each running process it finds. Depending on the resulting bit mask the further infection path is altered, e.g., if `avp.exe has been` encountered. QakBot will later inject its code into `mobsync.exe instead of` `explorer.exe .` Because the searched process names are related to security solutions, we believe that this way QakBot tailors its execution path to evade detection by specific vendors. Then in another loop, again using `CreateToolhelp32Snapshot and` ``` Process32{First,Next}W, it checks for: srvpost.exe frida-winjector-helper-32.exe frida-winjector-helper-64.exe ``` If it detects any of those processes the execution flow will run into a loop continuously calling ``` WaitForSingleObject(handle, 0x1fa) on a handle previously generated via CreateEvent(NULL, FALSE, FALSE, ...), i.e., it runs in an infinite loop. ``` **Device drivers** Next, QakBot uses `SetupDiGetDeviceRegistryPropertyA (querying properties` ``` SPDRP_DEVICEDESC and SPDRP_SERVICE ) to check for device drivers containing the ``` following strings: ``` VBoxVideo Red Hat VirtIO QEMU A3E64E55_pr ``` We believe the search for `A3E64E55_pr is used to detect an artifact of the ANY.RUN` sandbox.4 Alternatively, but unlikely, it could be used to detect an artifact of the long ago defunct xCore Complex Protection AV solution using a similar driver with the name ``` A3E64E55_pr.sys . ``` If it detects any of those device drivers the execution flow will run into the same infinite loop continuously calling `WaitForSingleObject(handle, 0x1fa) on a` `handle previously` generated via `CreateEvent(NULL, FALSE, FALSE, ...), as previously mentioned.` ----- **Process injection** QakBot starts `C:\Windows\SysWOW64\explorer.exe in suspended state and injects a DLL` into it using `CreateProcessInternalW,` `NtMapViewOfSection,` ``` NtAllocateVirtualMemory, WriteProcessMemory, memcpy, ``` ----- ----- [The injected DLL can be extracted via PE-sieve 5](https://github.com/hasherezade/pe-sieve) or other tools for simplyfied further analysis. Depending on whether the previous process enumeration yielded results on the list, QakBot will inject into `mobsync.exe (e.g., in case a` `avp.exe process is found running) instead of` ``` explorer.exe . But for simplicity we will only follow the explorer.exe process injection ``` path we observed in our analysis environment. ### C2 communication After avoiding detection, the injected QakBot code within `explorer.exe will start` communicating with the C2 servers. ----- Like in previous versions of QakBot the C2 IP list is stored RC4 encrypted in resource section `311 . The first 20 bytes of the section contains the RC4 key with which the rest of` the section is decrypted. The first 20 bytes of the decrypted data will contain the SHA1 sum calculated over the rest of the decrypted data. It is used as a verification for correct decryption. Unlike in previous version, the C2 list is now stored in binary form and not as ASCII text anymore. For details on how to extract the C2 list and QakBot’s configuration see the Python3 script in the appendix. The input to the script is the path to the DLL that QakBot injected into ``` explorer.exe, which we previously extracted via PE-sieve .5 ``` The configuration is stored using the same RC4 encryption scheme in resource section ``` 308 . In it we can see the bot and/or campaign ID abc103 that is associated with the ``` analyzed sample. It is still stored in plain ACSII text. For each campaign the number is ----- increased by one. This allows the operators behind QakBot to keep track to which campaign each victim connecting to their C2 server belongs to. Another currently observed identifier is ``` tr02 . This identifier, however, stayed the same over multiple malspam campaigns. ``` Via the C2 connection the operators behind QakBot can remote control the malware and deploy additional malicious modules. QakBot will not store its configuration and C2 list on disk anymore. It will use the registry for storage. ### Wiping The previous QakBot version used to overwrite its initial executable with a copy of ``` cmd.exe . This version will overwrite the portion of the initially downloaded DLL after the PE ``` header with zeros. Here is the entropy of the QakBot DLL as downloaded. ----- The zeroing of data after the header can be clearly seen when comparing the previous plot against a plot of the DLL file after wiping. ### Persistence The persistence mechanism of QakBot has also changed. While it still uses a run key registry entry under `HKCU\Software\Microsoft\Windows\CurrentVersion\Run, this key` is only set right before the system is shutdown, rebooted or put to sleep. The corresponding DLL is also only dropped to disk right before shutdown, rebooted or sleep. After the system boots up again, QakBot is started via the run key. The execution tree also starts via `regsvr32.exe -s ... like the initial execution from Excel. QakBot follows the` same steps as previously outlined resulting in process injection into `explorer.exe .` QakBot will then delete the run key registry entry and delete the DLL it dropped to disk prior to the reboot. ----- This way QakBot’s persistence can not be detected at runtime. ### Egregor [While we have previously reported on QakBot deliverying the ProLock ransomware, 2](https://www.hornetsecurity.com/en/security-information/qakbot-malspam-leading-to-prolock/) latests reports indicated that QakBot is now used to deliver the Egregor ransomware. We previously [reported on the Egregor ransomware as part of an article on ransomware leaksites6](https://www.hornetsecurity.com/en/security-informationen-en/leakware-ransomware-hybrid-attacks/) in which we explain the practice of ransomware operators stealing their victims data before encrypting it to extort them not only with decryption but also public release of the stolen data. ## Conclusion and Countermeasures From our analysis we can conclude that QakBot is trying to avoid persistent file artifacts. In previous version the configuration and QakBot executable were permanently stored on disk. This made it easy for security tools to detect them. The new version tries to avoid permanently leaving its artifacts on disk. While QakBot is not going fully fileless, it new tactics will sure lower its detection. But even though QakBot has changed, the delivery mechanism behind the QakBot “ abc[A``` Z]+ ” campaign did not. Hence, an infection by this threat actor can be successfully ``` prevented by blocking the initial emails. Hornetsecurity’s [Spam Filter and Malware Protection, with the highest detection rates on the](https://www.hornetsecurity.com/en/services/spam-filter/) market, already detects and blocks the outlined threat. Hornetsecurity’s Advanced Threat Protection extends this protection by also detecting yet unknown threats. ## References Indicators of Compromise (IOCs) ### Hashes The hashes of the analyzed QakBot samples are: ----- **MD5** **Filename** **Description** `6bc0584f6cbb74714add1718b0322655` `904400.jpg` QakBot DLL as downloaded by XLM macro `e23bc27212f61520cfb130185d74cfb1` `26e0000.dll` Extracted QakBot DLL ## MITRE ATT&CK The tactics and techniques used by QakBot as defined by the MITRE ATT&CK framework are as follows: **Tactic** **Technique** TA0001 – Initial Access T1566.001 – Phishing: Spearphishing Attachment TA0001 – Initial Access T1566.002 – Phishing: Spearphishing Link TA0002 – Execution T1027 – Obfuscated Files or Information TA0002 – Execution T1204.002 – User Execution: Malicious File TA0003 – Persistence T1547.001 – Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder TA0004 – Privilege Escalation TA0005 – Defense Evasion TA0005 – Defense Evasion TA0005 – Defense Evasion TA0005 – Defense Evasion TA0005 – Defense Evasion TA0006 – Credential Access TA0006 – Credential Access T1053.005 – Scheduled Task/Job: Scheduled Task T1027.002 – Obfuscated Files or Information: Software Packing T1055 – Process Injection T1055.012 – Process Injection: Process Hollowing T1070 – Indicator Removal on Host T1497.001 – Virtualization/Sandbox Evasion: System Checks T1003 – OS Credential Dumping T1110.001 – Brute Force: Password Guessing ----- **Tactic** **Technique** TA0006 – Credential Access TA0011 – Command and Control TA0011 – Command and Control TA0011 – Command and Control ## Appendix T1555.003 – Credentials from Password Stores: Credentials from Web Browsers T1071.001 – Application Layer Protocol: Web Protocols T1090 – Proxy T1090.002 – Proxy: External Proxy ### Qakbot configuration extraction Python3 script ``` import sys import pefile from arc4 import ARC4 pe = pefile.PE(sys.argv[1]) c2list = [] for entry in pe.DIRECTORY_ENTRY_RESOURCE.entries: for e in entry.directory.entries: n = e.name.string.decode() data = pe.get_data(e.directory.entries[0].data.struct.OffsetToData, e.directory.entries[0].data.struct.Size) data = ARC4(data[:20]).decrypt(data[20:])[20:] if n == '311': for i in range(1,len(data),7): c2 = list(data[i:i+6]) c2list.append("%d.%d.%d.%d:%d" % (c2[0],c2[1],c2[2],c2[3],(c2[4] <<8)+c2[5])) elif n == '308': config = data.decode().split() print("# QakBot Config\n\n```\n" + "\n".join(config) + "\n```\n") print("# QakBot C2\n\n```\n" + "\n".join(c2list) + "\n```\n") ``` -----