Cat Scratch Server: Getting Your Paws on DNScat2 & Other Suspicious DNS Activity

Cian Heasley
Adarma Tech Blog
Published in
8 min readJul 8, 2020

--

Introduction

There’s a saying among sysadmins, “It’s always DNS”. And in this case, it really is.

Today we will be exclusively looking at DNS based Command & Control (C2), tunnelling, exfiltration activity with log excerpts and some simple SPL for detection of popular red team tools.

A DNS haiku

We’re going to be primarily taking a look at DNScat2, a DNS based C2 along with iodine, which is a DNS based tunnelling tool and DNSExfiltrator- a tool to enable exfiltration of files over covert channels masked as DNS traffic.

All of these tools require that the adversary has control of an authoritative DNS server, which will serve as the endpoint for the DNS requests transmitted from the compromised host.

Each of these tools is comprised of a client that must be run on the system to be exploited and a server-side that is installed on the adversary’s staging server.

Throughout this piece, I’ll be aligning everything with Mitre’s ATT&CK Framework to keep us all on the same page as to what we’re discussing, and linking to resources for those who want more information.

We will be looking at Windows Event Logs and DNS records as our data sources of choice, although firewall logs would also be useful for detecting the kinds of traffic we’ll be looking for in some cases.

If you are interested in reading more about C2s, the C2 Matrix is an excellent resource that brings together metrics for comparing C2 capabilities and limitations.

The C2 Matrix Google Sheet

Methodology

Information presented here is current as of June 2020.

All of the information in this piece is derived from tests run on a fully up-to-date Windows Server 2012 or Windows 10 Enterprise VM acting as the compromised host running the client-side of each tool and a Debian system running the adversary’s server-side.

For anyone wanting to replicate my test setup, I recommend using zone forwarding within BIND on the server-side to handle relaying requests to the various DNS adversary tools. Using zone forwarding means it is possible to continue running BIND on port 53 whilst running the other servers themselves on your choice of ports and not having to mess with iptables or other more complex methods of getting everything to play nicely together.

The added bonus here is that queries that pass through BIND and are then forwarded are logged, which is, of course, vital for our testing and Splunk visibility.

Setting up zone forwarding in BIND’s named.conf.local for DNScat2 and iodine, server-side

To generate DNS background noise so that there was a greater amount of test data to parse I used “noisy”, which requests a series of websites, spiders them and then follows any links within them to generate traffic. You can run this on any computer that is using your test DNS server.

Running “noisy” to generate background DNS traffic

Finally, a Splunk Universal Forwarder is running on the DNS server so that we can ingest and analyse incoming queries and on the compromised host VMs.

DNScat2

DNScat2 uses port 53 (ATT&CK T1043: Commonly Used Port) to blend in with existing outgoing DNS traffic (ATT&CK T1071: Standard Application Layer Protocol), it can transfer files to and from compromised hosts (ATT&CK T1105: Remote File Copy) and by default uses ECDH and SHA3 implemented via salsa20 to encrypt data that passes between the client and host (ATT&CK T1022: Data Encrypted).

DNS as C2 or exfiltration has been observed in the wild in use by APT groups such as Oilrig, FIN7 and APT41.

DNScat2 server-side running on Debian

From the project Github:

This tool is designed to create an encrypted command-and-control (C&C) channel over the DNS protocol, which is an effective tunnel out of almost every network.

You can find pre-compiled DNScat2 binaries for popular platforms here.

Once you set a baseline for the length of the queries you see in your environment you can start to look for outliers, as DNSCat2 results in lengthier queries than legitimate traffic.

index=2012 sourcetype="isc:bind:query" query!=*local query!=*arpa
| eval qlen=len(query)
| eventstats avg(qlen) AS avg stdev(qlen) AS stdev
| where qlen>(stdev*3)
| table src query dest qlen avg
| sort -qlen

So we’ve seen that we can look at the length of queries themselves but what about analysing the contents of the queries? This is where URL Toolbox comes in - it enables us to work with the domains queried, separating multi-level subdomains from base domains, and also look at Shannon Entropy.

Explaining Shannon Entropy in detail is beyond the scope of this piece but in essence, it is a way of determining the probability of a series of characters occurring and flagging those that are less probable, or “surprising”.

Running this against our DNS query data we can look for values with high Shannon Entropy scores:

We can immediately see that our top results are all from my test domain “k0dez.org”, *.en1gma.k0dez.org is our DNSCat2 traffic, *.v0ynich.k0dez.org is the subdomain associated with iodine and *.d0rabella.k0dez.org is traffic from DNSExfiltrator.

URL Toolbox works well, you should install it if you are using Splunk.

Lastly, by default DNScat2 rotates through sending data as MX, TXT and CNAME record types. While it doesn’t send precisely a third of data as each type it is close enough to a third each that the following rough SPL should be able to catch it:

index=2012 sourcetype=”isc:bind:query” AND record_type IN (“CNAME”, “MX” “TXT”)
| eval utlist=”*”
| `ut_parse_extended(query, utlist)`
| stats count AS total count(eval(record_type=”MX”)) AS MX count(eval(record_type=”TXT”)) AS TXT count(eval(record_type=”CNAME”)) AS CNAME count(ut_domain) values(record_type) by ut_domain
| eval MXpercent=round(MX/total*100,2), TXTpercent=round(TXT/total*100,2), CNAMEpercent=round(CNAME/total*100,2)
| where MXpercent >= 30 AND TXTpercent >= 30 AND CNAMEpercent >= 30

Here are our results, note the percentage of each record type:

Iodine

As with our other tools, iodine uses port 53 (ATT&CK T1043: Commonly Used Port) to blend in with existing outgoing DNS traffic (ATT&CK T1071: Standard Application Layer Protocol), and it creates a tunnel between compromised host and server (ATT&CK T1048: Exfiltration Over Alternative Protocol).

You can find pre-compiled iodine binaries for popular platforms here.

From iodine’s Github documentation:

This is a piece of software that lets you tunnel IPv4 data through a DNS server. This can be usable in different situations where internet access is firewalled, but DNS queries are allowed.

Reading the win32 documentation for iodine, we can see that when the iodine client is compiled and run in Windows it requires an OpenVPN driver.

We can look for this installation of OpenVPN in Windows logs as a potential indicator:

index=win10 sourcetype="wineventlog:security" EventCode=4697 Service_File_Name="*openvpnserv*" OR Service_Name="OpenVPNService"
| table _time Account_Name ComputerName Service_File_Name Service_Name

Iodine uses NULL or PRIVATE records by default as these offer the most bandwidth for query lengths but can also use TXT, SRV, MX, CNAME or A, in descending order of usefulness to the adversary.

Queries with the NULL or PRIVATE record type is generally going to be less commonplace on your network, so let’s start with this as a way to hunt for iodine traffic, shall we?

Modifying our earlier Shannon Entropy scoring SPL to look specifically for two record types:

index=2012 sourcetype=”isc:bind:query” query!=*local query!=*arpa AND record_type IN (“NULL”, “PRIVATE”)
| eval list=”*”
| `ut_parse(query, list)`
| `ut_shannon(ut_subdomain)`
| table ut_domain query record_type ut_shannon
| sort -ut_shannon

We can also look at the number of queries:

index=2012 sourcetype=”isc:bind:query” query!=*local query!=*arpa AND record_type IN (“NULL”, “PRIVATE”)
| eval list=”*”
| `ut_parse(query, list)`
| `ut_shannon(ut_subdomain)`
| stats count AS Count by record_type ut_domain
| sort -Count

Though for our test data purposes there is, unfortunately, no non-suspicious NULL queries to compare traffic volume against.

DNSExfiltrator

DNSExfiltrator uses port 53 (ATT&CK T1043: Commonly Used Port) to blend in with existing outgoing DNS traffic (ATT&CK T1071: Standard Application Layer Protocol), it can transfer files from compromised hosts (ATT&CK T1105: Remote File Copy) and by default RC4 to encrypt data that passes from the client and host (ATT&CK T1022: Data Encrypted).

From the project Github description:

DNSExfiltrator allows for transferring (exfiltrate) a file over a DNS request covert channel. This is basically a data leak testing tool allowing to exfiltrate data over a covert channel.

DNSExfiltrator has a server-side that receives files and a client-side, which in my tests I invoked from a Powershell script hosted on Github by the tool’s creator.

Looking over the type of DNS queries that this tool sends when initiating a file exfiltration we can find some indicators in DNS logs that we can easily search for.

index=2012 sourcetype=”isc:bind:query” record_type=TXT (query=*init* OR query=*base64*)
| table _time query src dest

Interestingly DNSExfiltrator file transfer traffic, as it contains underscores and queries over 100 characters long, broke the regex that the Splunk ISC BIND app relies upon for field extractions in transforms.conf.If I had not known the events were there I would have missed them.

For testing purposes I transferred a text file containing the combined works of Sherlock Holmes from my Windows 10 client machine to the DNSExfiltrator server-side twice, to see what kind of traffic would be generated.

The answer is; a lot of traffic.

The SPL for the search above:

index=”2012" sourcetype=”isc:bind:query” record_type=TXT
| eval utlist=”*”
| `ut_parse_extended(query, utlist)`
| stats count AS queryCount BY ut_domain ut_subdomain_level_1

The queries during actual file transfer themselves look like this, really lengthy and distinctive:

In Conclusion

This is just a look at three open-source tools used by adversaries that take advantage of the DNS protocol for covert communications and we’ve covered a lot of ground here.

If you are currently working on a blue team I think playing around with the tools that red team uses and picking apart the resulting logs is really useful. I discovered potential flaws in the way that DNS logs are currently handled by Splunk purely because of this research, and it has given me a lot to think about.

If this article made you curious as to how well your company is looking at DNS logs or other data sources in your environment and you think you need some objective analysis performed by experts in the field then why not contact Adarma?

Lastly, I’d like to thank the creators and maintainers of the various red team tools we’ve looked at today for their time and effort and my team at Adarma for being awesome.

--

--

Cian Heasley
Adarma Tech Blog

I work in infosec and live in Scotland, I am fascinated by computer security, privacy and the intersection of the internet, technology and human rights.