Operation TA505: twins. Part 4

What are the security threats on your network?

Check your traffic-for free
Request pilot
Part of a series on the TA505 hacker group.

The old adage "everything old is new again" perfectly fits the latest chapter in the story of the TA505 group. Although in the case we are going to examine, the "old" has been well revised and enhanced on its way to becoming "new."

In the beginning of September we detected some malware downloaders packed by the group's unique PE packer described in one of our earlier articles. At first glance the downloaders appeared similar to the well-known stagers of the FlawedAmmyy backdoor. However, closer analysis proved otherwise. The less-than-cutting-edge coding techniques we found in them pointed the way to payloads that were implemented to a rather higher standard of quality.

This article will provide a detailed look at the detected malware and draw parallels with what is already known.

Twein downloader

Curiously, out of all the downloader samples that we managed to find, only one was digitally signed:

Figure 1. Twein's digital signature
Figure 1. Twein's digital signature

The certificate is issued in the name of PEAR SOLUTIONS LTD. This is not the first time TA505 has signed malware to make it look like legitimate software (albeit from fictitious organizations). Here are some names of organizations that TA505 has used for other malware families:

  • ET HOMES LTD,
  • FIT AND FLEX LIMITED,
  • MISHA LONDON LTD,
  • SATOJI KAIDA MB,
  • VERY TELE LIMITED.

Since the found downloaders are all similar, let us opt for the one mentioned above and focus on it.

When the malware is running, almost every action entails a trace record and debug output:

Figure 2. Debug output and tracing
Figure 2. Debug output and tracing

Such tracing facilitates static analysis of the file and also helps examine malicious activity via dynamic analysis:

Figure 3. Debug output on the ANY.RUN online analysis service
Figure 3. Debug output on the ANY.RUN online analysis service

The Trojan checks the keyboard layout to prevent it from running in Russia and some neighboring countries:

Figure 4. Keyboard layout check
Figure 4. Keyboard layout check

Then the downloader creates the mutex Global\system32_mutant_service and checks if the Internet is available by sending an HTTP GET request to google.com. After that, the Trojan tries to determine the type of Internet access (dedicated IP address or NAT) by identifying the external IP via myexternalip.com, ipecho.net, and ifconfig.me and comparing the obtained values with those specified in the system's network parameters:

Figure 5. Comparing the internal and external IP addresses
Figure 5. Comparing the internal and external IP addresses

Next, the malware identifies the version of the %SystemRoot%\system32\crypt32.dll library. If the build number and the revision number are less than 7601 and 18741 respectively, then the Trojan downloads and installs the KB3033929 update appropriate for the installed OS version:

Figure 6. Downloading and installing the system update
Figure 6. Downloading and installing the system update

Are the TA505 attackers so kind as to care about the victim's system and patch it when necessary? Not a chance. Installing the update ends support for SHA-1 code signing certificates, requiring SHA-2 instead. The hackers most likely had encountered difficulties launching signed payloads on non-updated systems. Having installed the update, the Trojan generates and sends a log to its С&C server, stops its activity, and removes itself from the system cleaning up the traces.

Figure 7. Operation ceasing after system update
Figure 7. Operation ceasing after system update

If installing the update is not needed, the downloader collects and sends the following data to the C&C server:

  • System data
  • Information on installed software
  • Data about signed software in the directories %ProgramFiles% and %ProgramFiles(x86)% (if any)
  • Information on signed drivers in the %SystemRoot%\drivers directory

Note that the attackers leveraged legitimate code to obtain information about digital signatures.

Figure 8. Obtaining certificate information
Figure 8. Obtaining certificate information

After that, the downloader creates the C:\Windows\Logs\diag directory and launches a thread in which it monitors changes in the directory and sends notifications to its C&C server:

Figure 9. Monitoring changes in the directory
Figure 9. Monitoring changes in the directory

Then the Trojan prepares already known and missing system information (username, system version, domain, IP address, video card information, and NAT vs. non-NAT Internet access) and generates a JSON file as follows:

{ "adm": "0", "bid": "M3xwwhqLH/AUOhmU2+W55A==", "bit": "1", "bnet": "ldr", "cam": "0", "cis": "0", "dmn": "WORKGROUP", "hash_r": "0", "lip": "192.168.100.153", "lvl": "0", "nat": "1", "osb": "0", "osv": "Windows 7 Professional", "pc": "USER-PC", "proc_c": "0", "proc_n": "cpu", "rep": 0, "tmt": "0", "ver": "163", "video": "Standard VGA Graphics Adapter," }

Later the data will be encrypted with RC4 (the encryption key gJypA9RWUlYpnBbzujVqE6fDcEAk0zoz is hardcoded in the Trojan's body), encoded with Base64, and sent in an HTTP POST request to a C&C server:

Figure 10. HTTP POST request to C&C server
Figure 10. HTTP POST request to C&C server
Figure 11. List of C&C servers in the downloader's body
Figure 11. List of C&C servers in the downloader's body

The server response undergoes RC4 decryption (the key is the same as the one used for sending the data). The first two bytes are checked to see if they equal the string MZ, indicating that it is a PE file. We have already encountered such a sequence before, when analyzing another TA505 downloader responsible for delivering the FlawedAmmyy RAT:

Figure 12. Similar decryption and code checking of the downloaded file by the downloader in question (on the left) and the FlawedAmmyy RAT (on the right)
Figure 12. Similar decryption and code checking of the downloaded file by the downloader in question (on the left) and the FlawedAmmyy RAT (on the right)

The payload is downloaded not only in the main thread, but also in a specially generated one. In other words, there are two payloads. In the case of one, the Global\system32_host_service mutex is checked, and if it is not present, the Trojan downloads the component named in the debug information as payload or bot. After the response is received from the server, the PE file does not run at at all. Instead, its body is written to registry hive HKEY_LOCAL_MACHINE\SYSTEM in key 0x228028. After that, the downloader disables redirection of the WoW64 file system for 32-bit applications via Wow64DisableWow64FsRedirection and starts the process %SystemRoot%\System32\services.exe with the parameter -ww. There is no point in using this parameter, but this is the last step in installing the payload.

Figure 13. Payload installation
Figure 13. Payload installation

We will discuss the second payload a bit later.

Twein plugins

As we studied the Trojan in question, a certain function caught our attention. It deletes the files twein_32.dll and twein_64.dll from the %SystemRoot% directory:

Figure 14. Deletion of twein_32.dll and twein_64.dll
Figure 14. Deletion of twein_32.dll and twein_64.dll

The files do not come up anywhere else and are not involved with the operation of the downloader. However, the names of these two libraries reminded us of some other malware from TA505 which we are going to discuss here.

Two months earlier we found a Trojan of the TA505 group approximately 9 MB in size. The file is packed by UPX. The Trojan is installed on the system as the WMDICToss service. The resources contain three files — systemdiron.bat, twein__32.dll, and twein__64.dll — encrypted by linear XOR.

Figure 15. Decoding one of the dropper's resources
Figure 15. Decoding one of the dropper's resources

Note that the names of the two files are almost the same as the file names we discussed earlier. The only difference is in the number of underscore characters.

One of the decoded resources with the name systemdiron.bat unsurprisingly turns out to be a command script, which ensures the start of other components as appropriate based on whether the system is 32-bit or 64-bit:

@echo off if defined PROCESSOR_ARCHITEW6432 (goto LABEL_X64) if %PROCESSOR_ARCHITECTURE%==IA64 (goto LABEL_X64) if %PROCESSOR_ARCHITECTURE%==AMD64 (goto LABEL_X64) if %PROCESSOR_ARCHITECTURE%==x86 (goto LABEL_X86) goto LABEL_NON :LABEL_X64 echo OS type: x64 copy c:\temp\tmp.log c:\i.txt rundll32.exe C:\Windows\twein__64.dll,Install copy c:\temp\tmp.log c:\i.txt rundll32.exe C:\Windows\twein__32.dll,Install del c:\temp\tmp.log del c:\i.txt shutdown.exe -r -t 00 goto LABEL_END :LABEL_X86 echo OS type: x86 copy c:\temp\tmp.log c:\i.txt rundll32.exe C:\Windows\twein__32.dll,Install del c:\temp\tmp.log del c:\i.txt shutdown.exe -r -t 00 goto LABEL_END :LABEL_NON echo OS type: undefined goto LABEL_END :LABEL_END pause

Both twein libraries operate in a similar way. They are both packed by a packer that is characteristic of TA505. Note the original name of the libraries: av_block.dll. The use of an obfuscator substantially complicates analysis. About 80 percent of the code is obfuscated. That is why execution of the program is full of jumps, code decryptions, and non-linear function calls.

The libraries contain a huge list of Base64-like strings that are decrypted in the following way:
1) The input string is divided into blocks of 4 bytes each.
2) Each block is decoded via an algorithm with substitution and shift:

import binascii def block_decode(input_str, len_of_block): alphabet = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3E\x00\x00\x00\x3F\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x00\x00\x00\x00\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x00\x00\x00\x00\x00\x00\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' int_result = 0 for i in range(len_of_block): alph = ord(alphabet[ord(input_str[i])]) alph <<= 0x6 * i int_result += alph str_result = hex(int_result)[2:] if len(str_result) % 2 != 0: str_result = '0' + str_result return binascii.unhexlify(str_result).decode('latin1')[::-1]

3) The blocks are assembled into a single string.
4) The result is decoded by the eexec algorithm with a 2-byte key, which is passed as a parameter:

Figure 16. Implementation of the eexec algorithm
Figure 16. Implementation of the eexec algorithm

The majority of the strings are file names and paths to antivirus software files. But some of them relate to Microsoft Exchange Server, MySQL Server, SAP, Apache, PostgreSQL, Elasticsearch, and others. Unique paths were found as well:

  • C:\Users\tislam\Desktop\salik app\Aye_salik_data\Aye_salik_data\bin\Debug\Aye_salik_data.exe
  • C:\oem13c\agent13c\agent_13.2.0.0.0\perl\bin\perl.exe
  • C:\Users\adadmin\Ubiquiti UniFi\bin\mongod.exe
  • C:\Users\sakella\AppData\Local\Microsoft\OneDrive\OneDrive.exe
  • D:\Add-ons\IMI_CREDIT_POLICY Test v 02.01\IMI_CREDIT_POLICY.exe

If the system is found to contain any software from the list, then the files and directories are deleted.

For persistence, the libraries install themselves as the Windows Sockets service provider interface (SPI) under the names of Intel and IntelFiltr. In addition, the libraries change the sequence of handlers in the protocol chain in order to become the first SPI to handle the client's request.

In 2015, researchers at FireEye reported on their analysis of LatentBot. The string encryption algorithm in LatentBot is absolutely the same as that in the twein libraries. Additionally, LatentBot uses a security module as one of its plugins. The module searches the system for specified paths and product names, although its activity does not extend beyond such checks.

Twein rootkit

We will now return to the topic of the downloader and, specifically, the second payload. The debug strings try to open rootkit... and Driver %S installed make it easy to guess the format of the subsequent payload. After successfully downloading, the driver is written to the directory %SystemRoot%\System32\drivers under a pseudorandom name that is generated from the names of other, legitimate files. Then the service is created and started:

Figure 17. Installation and start of the service
Figure 17. Installation and start of the service

At its final stage, the downloader configures the driver with deny lists in registry keys. It takes the names of antivirus processes, tools for analysis, and vendors of security tools from their digital signature files and adds them to the specified numeric values of the keys of the hive HKEY_LOCAL_MACHINE\SYSTEM:

Figure 18. Driver set up with deny lists
Figure 18. Driver set up with deny lists

While studying the downloader, we were unable to obtain a sample of the driver from the C&C server. However, we discovered a reference to a rootkit that was loaded by another similar downloader.

The driver is digitally signed to the name of Lizas Limited with the email address administrator@lizaslimited.site:

Figure 19. Driver digital signature
Figure 19. Driver digital signature

Studying this rootkit, we found many common characteristics with the well-known Necurs botnet, which TA505 widely used for sending spam and distributing its malware. Let us now have a closer look at how the rootkit operates.

The driver registers event handlers to run processes and download PE images via PsSetCreateProcessNotifyRoutine and PsSetLoadImageNotifyRoutine. In other words, the driver watches launch of all new processes and services. Using the deny lists we mentioned earlier, the rootkit terminates processes via ZwTerminateProcess. It also prevents the loading of other drivers that are potentially dangerous to it by overwriting the entry point value in the following way:

mov eax, 0C0000001 retn 8

This leads to unloading the service in normal mode with the error STATUS_UNSUCCESSFUL.

Figure 20. Process termination
Figure 20. Process termination
Figure 21. Overwriting the entry point for drivers
Figure 21. Overwriting the entry point for drivers

The driver intercepts system registry access events by using CmRegisterCallback. Namely, the driver's further operation is parametrized by the numeric values of the keys accessed in intercepted events.

Figure 22. Rootkit managing access to registry keys
Figure 22. Rootkit managing access to registry keys

In some versions of the Necurs rootkit, the same numeric values were used as ioctl request codes.

Figure 23. Managing Necurs via ioctl requests
Figure 23. Managing Necurs via ioctl requests

This trick can be considered a step towards greater stealth, because registry calls are less suspicious than ioctl requests to DeviceObject.

The rootkit body contains a helper DLL library encrypted with single-byte XOR. When a new process is created, the driver injects the library along with another PE file, which is extracted from the registry and is again decrypted with single-byte XOR.

Figure 24. Decryption and injection of the helper library into the created process
Figure 24. Decryption and injection of the helper library into the created process

The helper component is a custom reflective loader, which correctly loads the second PE file (which acts as payload) into memory and passes control to it. This can help understand how exactly the payload from the first part of the article (the one added by the downloader to the registry) starts operating.

Figure 25. Filling of import table by helper library
Figure 25. Filling of import table by helper library

Conclusions

The article has examined the characteristic features of certain twin Trojans. Why twins, you might wonder? The malware downloader covered in the beginning of the article is very similar in code quality and certain aspects of its implementation to the well-known downloader of the FlawedAmmyy backdoor. The twein libraries that the Trojan tries to remove from the system are, most likely, the very same libraries covered here. The libraries are extremely similar to the security plugin of LatentBot. One of the downloader payloads is a driver derived from the well-known Necurs rootkit.

Even with malware families that are more than five years old, the developers still continue updating and enhancing them to keep up with today's operating systems and security tools.

Authors: Alexey Vishnyakov and Daniil Koloskov, Positive Technologies

IOCs

a28a54abc30805cc6ea2ce0732989287 — Twein loader
f6b6526b8d494dce14568e3703368432 — Twein plugins dropper
983dd279722154a12093410067fe070e — Twein rootkit
Share this article:

Get in touch

Fill in the form and our specialists
will contact you shortly