In this post, we’ll use regular expressions and TLS certificate analysis to identify 83 scattered Qakbot servers.
These servers are crafted to avoid traditional detection methods—there are few consistent patterns in ports, service names, or ASNs that could be used for simple signatures. Instead, we’ll focus on shared attributes within the subject_dn
and issuer_dn
fields to identify them.
This method is somewhat advanced and requires a basic knowledge of regular expressions, as well as a paid or researcher license for Censys.
services.tls.certificates.leaf_data.subject_dn=/C=\w\w, OU=[a-zA-Z0-9 \.]+, CN=[a-z]+\.[a-z]+/ and services.tls.certificates.leaf_data.issuer_dn=/C=\w\w, ST=\w\w, L=[a-zA-Z]+, O=[a-zA-Z0-9\. ]+, CN=[a-z]+\.[a-z]+/
Note that this post is primarily a demonstration of technical concepts that can be used to identify malware. We have not 100% validated that all results are Qakbot (although most appear to be), and we are relying on the initial ThreatFox tag being accurate.
Initial Server From ThreatFox
The initial server IP of 74.12.147[.]243:2222
was obtained from ThreatFox. Initially shared by the Twitter user @drb_ra.
By searching the IP address on Censys, we can quickly identify a suspicious certificate running on the reported 2222
port.
This certificate contains seemingly random text. With long values and only alphabetical characters.
Using “View All Data”, we can gather more information about the service running on 2222
.
This reveals an empty service banner that can be later used as a pivot point or as a field to narrow down search results.
The exact structure of the TLS Certificate can be established with this view.
The search box next to services.tls.certificates.leaf_data.subject_dn
can be used to pre-build an exact query.
We will use this pre-built query as a base for our regular expression.
How To Convert Values Into Regular Expressions
We can go ahead and modify the search parameter to a regular expression.
A summary of the changes can be found below.
C=US
->C=\w\w
– We will let theC
field matches on any two charactersOU=Vzbxanrbu Eivhtmjiabe Qjihwitl
->OU=[a-zA-Z0-9 ]+
– We can let theOU
field matches any sequence of alphabetical characters, allowing for a space in between.CN=motnooz.biz
->CN=[a-z]+\.[a-z]+
– we will let theCN
field match on any domain containing only lowercase letters.
After modifying the query as above, we can also add a filter for our original IP. This ensures that the same IP is matched and hasn’t been lost. This is a means of quickly verifying that a regex works as intended.
We can see below that the same Initial IP is matched, meaning that the regex probably works.
With the Regex validated, We can now go ahead and remove the IP Address, leaving only the subject_dn
field.
This modified search results in 778 servers, many of which don’t completely follow the certificate structure we want.
Validating Search Results
If we inspect the first returned result of 75.98.168[.]215
, we can see that the subject_dn
matches our regular expression structure, but the issuer_dn
is different to our initial Qakbot.
Below is the first returned result (Which does not match our pattern). Note that it contains the -
character in the CN
and O
fields.
Below is the original Qakbot C2. Note the lack of special characters and numerical values.
Refining Threat Intel Queries with Extra Fields
The initial search returns results that match our subject_dn
regular expression.
But there are results with a completely different (and not matching) structure on the issuer_dn
.
We can go back to our initial Qakbot C2 and follow the same process as before to build a regular expression on the issuer_dn
field.
We can then validate the regular expression by including the initial IP address.
Since the issuer_dn
field has not been validated; We can now go ahead and add the issuer_dn
query to the initial subject_dn
search. We can also include the initial IP for validation.
At this point, we have a total query of
services.tls.certificates.leaf_data.subject_dn=/C=\w\w, OU=[a-zA-Z0-9 \.]+, CN=[a-z]+\.[a-z]+/ and services.tls.certificates.leaf_data.issuer_dn=/C=\w\w, ST=\w\w, L=[a-zA-Z]+, O=[a-zA-Z0-9\. ]+, CN=[a-z]+\.[a-z]+/ and ip:70.27.15.38
The above search confirms that we haven’t lost our initial hit, meaning the regex is valid, and the initial IP can be removed.
By removing the Initial IP Address and including only the subject_dn
and issuer_dn
, we’re now down to a manageable number of 83 results.
Inspecting the first two hits, we can confirm that we have matches on our intended certificate structure.
Further Validation With Report Building
To save time validating every result individually, we use the “build report” function of Censys to hone in on the subject_dn
or issuer_dn
fields.
This confirms that most of the returned servers match our intended structure.
Honing in on Domain/Host Names
We can also use the “build report” function to hone in on common_name
fields used in the TLS certificates.
Query Refinement
There are potentially some false positives within the 83 returned results, so if we like, we can go ahead and add the empty banner hash from the initial IP.
This will reduce the hits down to 49. But it’s possible that this may remove some malicious results. I did not validate this as it’s very time-consuming, and the majority of servers seem to be malicious either way.
Validating Results With Virustotal
Performing a quick search on some of the returned hits on Virustotal.
Most seem related to Qakbot, although we have not confirmed this 100%.