Use of DNS Tunneling for C&C Communications
– Say my name.
– You are goddamn right.
Network communication is a key function for any malicious program. Yes, there are exceptions, such as cryptors and ransomware Trojans that can do their job just fine without using the Internet. However, they also require their victims to establish contact with the threat actor so they can send the ransom and recover their encrypted data. If we omit these two and have a look at the types of malware that have no communication with a C&C and/or threat actor, all that remains are a few outdated or extinct families of malware (such as Trojan-ArcBomb), or irrelevant, crudely made prankware that usually does nothing more than scare the user with screamers or switches mouse buttons.
Malware has come a long way since the Morris worm, and the authors never stop looking for new ways to maintain communication with their creations. Some create complex, multi-tier authentication and management protocols that can take weeks or even months for analysists to decipher. Others go back to the basics and use IRC servers as a management host – as we saw in the recent case of Mirai and its numerous clones.
Often, virus writers don’t even bother to run encryption or mask their communications: instructions and related information is sent in plain text, which comes in handy for a researcher analyzing the bot. This approach is typical of incompetent cybercriminals or even experienced programmers who don’t have much experience developing malware.
However, you do get the occasional off-the-wall approaches that don’t fall into either of the above categories. Take, for instance, the case of a Trojan that Kaspersky Lab researchers discovered in mid-March and which establishes a DNS tunnel for communication with the C&C server.
The malicious program in question is detected by Kaspersky Lab products as Backdoor.Win32.Denis. This Trojan enables an intruder to manipulate the file system, run arbitrary commands and run loadable modules.
Just like lots of other Trojans before it, Backdoor.Win32.Denis extracts the addresses of the functions it needs to operate from loaded DLLs. However, instead of calculating the checksums of the names in the export table (which is what normally happens), this Trojan simply compares the names of the API calls against a list. The list of API names is encrypted by subtracting 128 from each symbol of the function name.
It should be noted that the bot uses two versions of encryption: for API call names and the strings required for it to operate, it does the subtraction from every byte; for DLLs, it subtracts from every other byte. To load DLLs using their names, LoadLibraryW is used, meaning wide strings are required.
‘Decrypting’ strings in the Trojan
Names of API functions and libraries in encrypted format
It should also be noted that only some of the functions are decrypted like this. In the body of the Trojan, references to extracted functions alternate with references to functions received from the loader.
The principle behind a DNS tunnel’s operation can be summed up as: “If you don’t know, ask somebody else”. When a DNS server receives a DNS request with an address to be resolved, the server starts looking for it in its database. If the record isn’t found, the server sends a request to the domain stated in the database.
Let’s see how this works when a request arrives with the URL Y3VyaW9zaXR5.example.com to be resolved. The DNS server receives this request and first attempts to find the domain extension ‘.com’, then ‘example.com’, but then it fails to find ‘Y3VyaW9zaXR5.example.com’ in its database. It then forwards the request to example.com and asks it if such a name is known to it. In response, example.com is expected to return the appropriate IP; however, it can return an arbitrary string, including C&C instructions.
Dump of Backdoor.Win32.Denis traffic
This is what Backdoor.Win32.Denis does. The DNS request is sent first to 188.8.131.52, then forwarded to z.teriava[.]com. Everything that comes before this address is the text of the request sent to the C&C.
Here is the response:
DNS packet received in response to the first request
Obviously, the request sent to the C&C is encrypted with Base64. The original request is a sequence of zeros and the result of GetTickCount at the end. The bot subsequently receives its unique ID and uses it for identification at the start of the packet.
The instruction number is sent in the fifth DWORD, if we count from the start of the section highlighted green in the diagram above. Next comes the size of the data received from C&C. The data, packed using zlib, begins immediately after that.
The unpacked C&C response
The first four bytes are the data size. All that comes next is the data, which may vary depending on the type of instruction. In this case, it’s the unique ID of the bot, as mentioned earlier. We should point out that the data in the packet is in big-endian format.
The bot ID (highlighted) is stated at the beginning of each request sent to the C&C
Altogether, there are 16 instructions the Trojan can handle, although the number of the last instruction is 20. Most of the instructions concern interaction with the file system of the attacked computer. Also, there are capabilities to gain info about open windows, call an arbitrary API or obtain brief info about the system. Let us look into the last of these in more detail, as this instruction is executed first.
Complete list of C&C instructions
Information about the infected computer, sent to the C&C
As can be seen in the screenshot above, the bot sends the computer name and the user name to the C&C, as well as the info stored in the registry branch Software\INSUFFICIENT\INSUFFICIENT.INI:
- Time when that specific instruction was last executed. (If executed for the first time, ‘GetSystemTimeAsFileTime’ is returned, and the variable BounceTime is set, in which the result is written);
- UsageCount from the same registry branch.
Information about the operating system and the environment is also sent. This info is obtained with the help of NetWkstaGetInfo.
The data is packed using zlib.
The DNS response prior to Base64 encryption
The fields in the response are as follows (only the section highlighted in red with data and size varies depending on the instruction):
- Bot ID;
- Size of the previous C&C response;
- The third DWORD in the C&C response;
- Always equals 1 for a response;
- Size of data after the specified field;
- Size of response;
- Actual response.
After the registration stage is complete, the Trojan begins to query the C&C in an infinite loop. When no instructions are sent, the communication looks like a series of empty queries and responses.
Sequence of empty queries sent to the C&C
The use of a DNS tunneling for communication, as used by Backdoor.Win32.Denis, is a very rare occurrence, albeit not unique. A similar technique was previously used in some POS Trojans and in some APTs (e.g. Backdoor.Win32.Gulpix in the PlugX family). However, this use of the DNS protocol is new on PCs. We presume this method is likely to become increasingly popular with malware writers. We’ll keep an eye on how this method is implemented in malicious programs in future.