The emails can be jarring, but the technique used by Qakbot (aka Qbot) seems to be especially convincing: The email-borne malware has a tendency to spread itself around by inserting malicious replies into the middle of existing email conversations, using the compromised accounts of other infection victims. These interjections in the form of a reply-all message include a short sentence, and a link to download a zip file containing a malicious office document, one that brings down the malware when someone opens it.
Because the malware is so good at doing this — quoting the original message after its malicious reply — it can be challenging for the targets of these attacks to recognize that the messages they receive didn’t come from the human being who owns the email box where they originated. It happens on a daily basis, even on an email listserv to which I subscribe.
The messages generally contain brief text content, followed by a link to download a zip archive. These links may be “bare URLs” like above, or hotlinked text in the message body, like these examples:
English-language variant versions of Qakbot spam reply text
The malicious email-replies sometimes appear in the presumed language of the recipient, such as these ones in German.
Qakbot has seen a resurgence in recent months as competing, email-driven botnets like Emotet and Trickbot have suffered setbacks as a result of action by law enforcement and tech companies (and, most recently, the leaks of internal data by disgruntled former criminal partners).
Like those families, the Qakbot malware is modular, with a core engine component and, potentially, multiple malicious plugins or components it will download and inject into system processes. It’s worth exploring the behavior of this particular campaign as an indication of the range of capabilities the bot has, since it seemed to use a lot of them.
In the incident that piqued my interest, where the attackers sent a reply to a listserv announcement about a musical performance, the malware delivered at least three different payloads, including a web injector for stealing login credentials and an ARP-scanning component that attempted to profile the network on which it was running. The same initial malware I infected a testbed with in October remains functional and capable of reaching its command-and-control server — it still gets payload updates, even five months later.
If it quacks like a duck
The message I received contained a simple comment: “Good day. If it will not cause any inconvenience, please reply to the last paperwork I sent. In case the message might not arrived, please do it right now.” Earlier the same day, a student at a nearby university sent a notice about the music performance, and it’s unusual to see someone reply to a general announcement like this on a large listserv, so I took another look.
Qakbot’s malicious Excel .xlsb files have had the same appearance for some time
It turns out that this message was just one of hundreds of variants I was able to find in a system Sophos uses to track spam samples. The messages all included a URL (one that wasn’t hotlinked, so you’d have had to copy the link from the message and paste it into a browser’s address bar); The URL itself was distinctive because it contained a few terms in Latin (nulla quia, which means “not because”) and the filename of the payload was also a Latin word (eum, or “him”). Other campaigns circulating at around the same time also used combinations of words in Latin in the URL.
The eum.zip file contained a malicious Excel spreadsheet with an unusual .xlsb (Excel Binary Workbook) extension. Opening the spreadsheet (and clicking the Enable Content button in Excel) triggered it to execute a payload embedded in the .xlsb file. That payload, dropped into a randomly named (five letters long) folder the bot created in the root of the C: drive, briefly contacted a compromised website using the Edge browser, and then injected itself into an instance of Edge, or Explorer, or sometimes both.
The malicious .xlsb file triggers regsvr32 to load DLL payloads it drops in a five-character folder name on the root of the C: drive
The malware continued engaging in a variety of malicious behaviors, which included profiling the machine it was running on, retrieving the public-facing IP address, and then downloading a series of payloads whose appearances coincided with other behavior I observed on the test system.
What’s a Qakbot gotta do?
Once the bot had established itself on the system, injected into instances of Exporer.exe and Msedge.exe, it began to retrieve a variety of malicious payloads and inject them into additional instances of the two system programs. The main malware payload, injected into Explorer, beaconed to its command and control server roughly every five minutes. This C2 address has remained active and available for at least five months.
Qakbot abusing Excel to retrieve and execute payloads in a “Jambo” directory
But the truly interesting behavior took place when the bot activated one or more of its payload DLLs. One of these payloads appears to have been used as a Web proxy, since the malware opened a session to a website’s administrative interface, using apparently stolen credentials, and uploaded several files to the website’s hosting storage area. Another payload resolved the addresses of a dozen SMTP servers and then attempted to connect to each one and send spam.
A Qakbot infected computer performs an ARP scan of the internal network
But the most troubling payload gave me pause. This payload performed an ARP scan of the entire IP address range of the testbed’s NAT network address space, presumably to look for a way to move laterally to other machines on the network.
The presence of Qakbot infections, generally, also correlates highly with the precursor indicators that a ransomware attack may begin shortly. We’ve encountered Qakbot samples that deliver Cobalt Strike beacons directly to the infected host, providing the operators of the botnet with a secondary revenue stream: Once the Qakbot-operating threat actors have used the infected computer to their satisfaction, they can then lease out or sell access to the compromised network by transferring access to these beacons to other threat actors.
Decoding Qakbot qakking
Qakbot, both the malware itself and its command-and-control messaging, is marked by elaborate levels of obfuscation and encryption. In the malware, the creators have put considerable effort into concealing sensitive strings, configuration data, and C2 addresses. The malware also caches data in the Windows Registry in an encrypted format, in a key it creates during the infection process.
In the communications, they’ve also created an elaborate mechanism for encrypting each C2 communication with a unique key to make it harder to figure out what the bot is telling its operators about the infected system. And as with Dridex, the bot uses a hash table lookup mechanism to conceal which operating system API calls it uses.
In the course of analyzing these bots, we spent some time to understand the communication mechanism and figured out how to decrypt the messages the bot sends and receives.
Qakbot code for executing WMI commands on the infected host
Qakbot uses WMI commands for a variety of functions: It queries aspects of the operating system in order to create a profile of the infected machine, fingerprinting a variety of components. It also can use WMI commands to copy files and folders, and to invoke other Windows executables as well. The bots, for example, query the operating system using WMI to determine what endpoint security software is installed. The specific WMI commands have been obfuscated with XOR.
The C2 communications between the bot and its controllers is done through HTTPS POST and GET requests, with the data transmitted in an encrypted format, wrapped inside TLS. Once you strip away the TLS layer, the communications protocols are visible, but the traffic is still in an encoded form. In the case of this bot, it was performing regular HTTPS POSTs to any of several IP addresses, always using the path /t4 and (at least with the bots we tested against) the User-Agent string Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko.
Qakbot HTTPS POST data (red) and C2 server response (blue)
This encoded data, which appears just as a blob of base64-encoded text, can be hard to decode because the bot generates an encryption key for each message, with part of the key being the first few characters of the message, and a static salt value.
Qakbot stores encoded data inside a randomly-generated key in the Windows Registry
It also generates a unique key on the infected machine for information stored in the bot itself, and for information it stores in the Windows Registry, using characteristics from the infected computer and operating system to dynamically create a key that’s unique to each machine.
Without getting into the details, we were able to devise a method to decode those messages and reveal the contents. When decrypted, the data appears in a JSON format.
For example, the message from the bot (text in red, above) looks like this when decoded:
and the response from the server (text in blue, shown above):
Now, clearly, this also uses yet another layer of encoding scheme, but one that we can translate by using a key we’ve devised. The pattern it follows is a numeric value wrapped in quotation marks, a colon character, and then a second value. A communication flow can contain several of these types of message pairs.
The number in quotation marks translates to a table of “message types” that we’ve interpreted using this key:
‘1’ : ‘PROTOCOL VERSION’,
‘2’ : ‘BOTID’,
‘3’ : ‘CAMPAINGID’,
‘4’ : ‘BOT VERSION HI’,
‘5’ : ‘BOT VERSION LOW’ ,
‘6’ : ‘BOT UPTIME’,
‘7’ : ‘SYSTEM UPTIME’,
‘8’ : ‘MSGTYPE’,
‘9’ : ‘[TBD]’,
’10’: ‘SYSTEM TIMESTAMP’,
’15’: ‘SIGNED (SALT|CMDID|MODULEID)’,
’16’: ‘EXTERNAL IP’,
’18’: ‘MODULE ID’,
’19’: ‘COMMAND ID’,
’20’: [‘MODULETYPE’, Base64 PAYLOAD],
’38’: ‘ACK [TBD]’,
’39’: ‘RND STRING’
So in that initial communication above the bot is telling the command-and-control server that the BOTID is pqqjdl158536, the MSGTYPE is 9, and the PROTOCOL VERSION is 18.
The response from the server tells the bot that the MSGTYPE is 5, the EXTERNAL IP of the infected machine is 220.127.116.11 (represented here in dotless IP address format, 2920293983), and what we suspect is an acknowledgment at the end.
Using this decoding method, we can read and follow along the entire conversation between the bot and its C2 server. We may not know exactly what a “MSGTYPE 5” means but we can infer from the context that it’s a regular check-in.
Rather than showing what ends up looking like a bunch of JSON formatted data, we decided instead to make it a little easier to understand the back-and-forth conversation between the bot and its C2. These are our interpretation of the first few minutes of the bot beaconing to its operator and receiving instructions (when the server responded, which it periodically just didn’t).
In its initial connection to the C2 server, the bot also transmits a very large data blob back to its C2. When we decoded that, we found an extremely detailed profile of the infected machine: Not just the speeds and feeds, but data about the configured user accounts (and their permissions), installed software (and the software’s associated registry keys), loaded drivers (and their registry keys), a list of running services and Scheduled Tasks, netstat output, and a list of running processes.
Decoded into plain text, the file was more than 1.4MB in size, and a rich source of information about my own testbed that was enlightening even to me.
The bot also received large data blobs from the C2 server itself; Most of these were DLL payloads that the bot decrypted, loaded into a hollowed-out system process, and executed filelessly. Some of these blobs were “webinjects” rules — large data files that define the way the bot will intercept the credentials when the user enters their username and password into Web-based login forms on dozens of popular websites.
The short list of websites Qakbot is interested in include many of the usual suspects (Facebook, Microsoft, and Google), as well as banking and finance-related websites.
Detection and advice
Qakbot is a versatile malware family with a growing popularity among a wide variety of criminal groups, who may use the malware itself or any of its variety of payloads to accomplish tasks. Its abuse of email threads make it particularly dangerous, as mail recipients may not realize that the Qakbot-spreading email messages are not just part of an ongoing conversation between multiple parties.
The easiest advice is to treat email with a reflexive distrust unless demonstrated to be otherwise, even when messages appear to come as replies to existing email threads. While the attackers seem to have moved on from the use of Latin phrases in their URLs, one aphorism in that ancient language appears to remain good advice: Caveat lector – let the reader beware.
Existing behavioral protections should prevent Qakbot infections from taking hold on machines protected by Sophos Endpoint products. Network devices will also alert administrators if an infected user attempts to connect to a known C2 address or domain. Samples related to this incident may be detected as Mal/EncPk-AQC and some payloads (notably, the webinjects code) will be detected as Mal/QbotDat-A.
SophosLabs has posted IOCs relating to the Qakbot samples analyzed in this report on out Github repository.