Analyzing Qakbot using Brim’s No-code threat hunting

Oliver Rochford
Brim Security
Published in
6 min readJan 14, 2021

Qakbot is the newest guise of Qbot, a banking trojan that was first detected in the wild in 2009. Originally focused on the theft of banking credentials via keystroke logging, it has since evolved to deliver a variety of payloads. More recently it has been in the news headlines for increased activity conducting Malspam campaigns.

As mentioned above, the iteration of Qakbot we’ll be looking at includes a Spambot payload, so we’ll be looking for SMTP traffic. The sample we are using also has another interesting characteristic. It uses Cobalt Strike for Command & Control (C2). Cobalt Strike is a commercial penetration testing tool. It includes a wealth of functionality including remote command execution, key logging, file transfer, privilege escalation and lateral movement. It also offers C2 over HTTP, HTTPS, DNS, and SMB. Pirated versions of Cobalt Strike have been leaked, resulting in the tool increasingly being seen utilized by malicious threat actors.

I’m also going to show you how to do this investigation using Brim without typing a single character — you read right — no-code threat hunting is here.

You can grab the pcap here, with further artefacts such as Indicators of Compromise (IOC) are additionally available here.

If you are just getting started with Brim, you can download it here and follow our installation instructions. Brim is a full nano network intrusion detection and threat hunting platform, and best of all, it’s open source. There is no need to install half a SOC or a dozen databases on a laptop to run a breach assessment or conduct a threat hunt. All you need is network data and Brim.

Getting the lay of the land

Brim includes an embedded Zeek engine, so we’ll begin by reviewing the Zeek streams that were generated during the pcap ingest. Brim’s query library can be found in the left hand panel and provides a standard query, “Activity Overview”, to accomplish this.

We can see a high number of HTTP and DNS requests. Noticeable are also the 11 SMTP records.

The count of Zeek records by stream via the “Activity Overview” query

Email and Spam, Spam Spam, Spam

Let’s pivot to the SMTP records via right-clicking the “smtp” entry and selecting the “Pivot to logs” option. This executes a query that isolates those 11 SMTP records.

Right-click on an entry and select “Pivot to logs”

Host “10.12.7.101” is sending emails to a diverse set of SMTP servers and recipients, but what really sticks out is the variety of sender addresses. We would ordinarily expect the senders to be consistent and originating from a set of shared company addresses. Either the SMTP server is an open mail relay, or someone is sending out spam.

This looks like Spam — note the variety of senders and recipients!

Investigating DNS traffic

Another interesting set of records to look at is DNS. We’ll use the “Unique DNS Queries” query from the query library.

Count of unique DNS queries

We can clearly see a large number of low count DNS requests for a variety of what at first glance appear to be SMTP servers, strengthening our identification for an active instance of SpamBot.

Reviewing HTTP(S) activity

We also want to see what’s going on with HTTP(S). We can leverage Brim’s query library for this again, by using the “HTTP Requests” query. It will present an overview of the count of unique HTTP requests. The Windows Update address is legitimate, but the “amajai-technologies.work” host looks suspicious, especially under the .work TLD. We also see the host,“10.12.7.101” again that we identified as sending out spam.

Overview of unique HTTP requests

At this juncture, we want to enrich our data with some threat intelligence by right-clicking on the suspicious host field and selecting “VirusTotal Lookup”.

Pivot from the “host” field to VirusTotal

The domain is known to be bad, and has been tagged as serving Qakbot with Cobalt Strike. We can now safely assume that the host “10.12.7.101” has been infected.

Hit! VirusTotal confirms the domain is known bad

Identifying C2 via File Activity

So far we have identified ongoing spam activity, and also identified a host the infected system is communicating with as malicious. Next we want to look into what files were seen, to try and identify the initial infection or C2 traffic.

Reviewing File transfer activity

There are multiple connections to different internet servers with the mime type “zip”. Qakbot is known to obfuscate its C2 traffic using zipped files, so we want to investigate these further.

We can use VirusTotal again, but this time we will correlate the MD5 hash:

VirusTotal correlation using the MD5 hash.

All of the listed hosts are known to serve malware, providing us with a list of IoC’s, for example to add to watchlists. The initial infection does not appear to be present in the pcap sample.

VirusTotal lookup against the MD5 hash comes up positive

So far, not a single character has had to be typed during our threat hunt. But if you want to export the IoC’s in a more tailored manner, you can trim down the fields to export. We’re going to extract the list of malicious IP addresses using this short Z query:

filename!=null mime_type=”application/zip” | cut rx_hosts

This will provide us with a list of all of the destination IP’s that have a file name and a mime_type of “application/zip”. If we want to share the list with colleagues that aren’t yet Brim users, we can now export the list in CSV or NDJSON format by using the “export” function.

Exporting the data in CSV or NDJSON

The view through Suricata Alerts

So far we have relied solely on our Zeek output, but Brim also has an embedded Suricata IDS engine. From the query library select the “Suricata Alerts by Category” query. You will be presented with a list of Suricata alerts by severity.

Overview of Suricata alerts using the query library

While there’s nothing that screams “Malware” at first glance, there are a high number of “Potentially Bad Traffic” alerts. If we right-click on the “alert.category” field for the alert, we can use “Pivot to logs” again to review the relevant records.

Pivoting into the “Potentially Bad Traffic” Suricata alerts

We see a number of hits for signatures highlighting that HTTP and DNS requests were made to *.work and *.biz domains originating from our Patient X “10.12.7.101. These types of domains are frequently used by malware operators.

We’ll go through the same workflow for the “Unknown Traffic alerts”. We can see that Suricata has flagged a number of suspicious connections using the JA3 hash, identifying both Qakbot, and also the Gozi malware, all originating from the infected host “10.12.7.101”. Also note the frequent use of the tcp port 8888.

“Unknown Traffic” alerts detecting Gozi and Qakbot via the JA3 Hash

Lastly, we get further validation when we send the destination IP’s to VirusTotal.

Cobalt Strike detected!

We can now export the output to CSV or NDJSON for further analysis or IoC gathering, as we outlined earlier

Conclusion

Just using the standard Brim query library and right-click pivoting, filtering and correlation we were able to validate the infection, identify our Patient X, identify some of the additional Qbot payloads, and determine a list of C2 hosts. This did not require a single character to be typed.

If you haven’t yet, check out Brim. It’s simply the most beautiful way to explore security data.

And if you have any questions, or just want to connect to other threat hunters using Brim, you are welcome to join our Slack Channel.

--

--

Oliver Rochford
Brim Security

Oliver is a Security Subject Matter Expert at Brim Security