Introduction
In April 2022, PT Expert Security Center detected an attack on a number of Russian media and energy companies that used a malicious document called «list.docx» to extract a malicious payload packed with VMProtect. Having analyzed the network packet, we found it to be identical to the one we studied in our report on APT31 tools, suggesting that these may belong to one and the same group. The malware samples date from November 2021 to June 2022.
Detailed analysis (see the "Attribution" section) of the unpacked malware confirmed our assumptions, as the malicious payload under VMProtect was indeed identical to the one we examined earlier.
Further monitoring revealed a number of documents used in attacks on the same companies with content similar in terms of the techniques used (see the "Malware analysis" section), yet differing from what we saw earlier both in the network part and the code implementation.
Detailed analysis of the tools showed the use of the Yandex.Disk service as the C2 server. This seemed a rather curious case to us, since it involved a potentially foreign group using a Russian service specifically to make the network load look outwardly legitimate.
The technique is not new, having been deployed by the TaskMasters group in its Webdav-O malware. The point of this technique is to bypass network defenses by connecting to a legitimate service.
This group's previous use of the Dropbox cloud service, as well as overlaps with the above-mentioned tools, suggests that here too we are dealing with the toolkit of the APT31 group.
This report describes the tools and techniques and their features, discusses the similarities and differences, and lays out the characteristics on which basis we assigned them to the APT31 group.
Analyzing malicious documents
The source document we started our research with (Figure 1) uses the Template Injection technique to download a template with a macro that loads malicious components (a legitimate file, a Java component, a malicious msvcr100.dll packed with VMProtect) from a remote server.
The template macro, a snippet of which is shown in Figure 2, creates files at the following path: C:\ProgramData\KasperskyOneDrive. The main task of the legitimate file is to transfer control to the malicious library using the DLL Side-Loading technique and generate an initializing packet that is sent to C2 (see the "Attribution" section).
During a further search for similar threats, a number of documents were found with the Author field equal to pc1q213 (Figure 3), containing an identical Base64 decoding code.
Analysis of the detected documents clearly showed their external similarity (Figure 4). Moreover, the code of the macros contained in them is identical all the way up to the names of the functions and variables (Figures 5 and 6).
A characteristic feature of all the documents is that they contain components for exploiting DLL Side-Loading to run the malicious payload inside them, as well as the external similarity of macros embedded in the documents and the Base64 encoding of the payload inside the documents.
The extracted payload also shows a number of similarities:
- Most of the binary files are packed with VMProtect;
- All the identified legitimate executable files are components of Yandex.Browser and signed with a valid digital signature;
- winhttp.dll and wtsapi.dll were used as malicious libraries under the guise of legitimate ones (in particular, by the presence, number, and names of exports).
Malware analysis
Our analysis identified two new types of malware, which we named YaRAT (because it has RAT functionality and uses Yandex.Disk as C2) and Stealer0x3401 (because of the constant used in obfuscating the encryption key). What's more, we saw YaRAT in two modifications: with token encryption inside the program code, and without it.
YaRAT
The Yandex.Browser installer signed with a valid Yandex digital signature, or its portable version, was used as a legitimate file vulnerable to the Side-Loading DLL. The file loads and calls a function in the malicious winhttp.dll.
And here's an example of function calls inside a legitimate binary file.
The malicious library itself is packed and encrypted, and is unpacked by calling DllEntryPoint, which happens whenever the library is loaded. In this case, DllEntryPoint contains code similar to UPX, which is probably borrowed but slightly modified.
The first stage also involves unpacking LZMA, after which the unpacked data is decrypted twice (code sections and other sections (imports, data, etc.) are decrypted separately).
The data is decrypted using the RC4 algorithm; both encryption keys are embedded in the code. A distinctive feature of both data decryption blocks is the type of code obfuscation (Control Flow Flattening), which hinders static analysis. Alongside this technique, an extra byte (0xB9) is inserted inside the function body, which confuses the disassembler and prevents it from generating the function's decompiled form.
An example of the code responsible for data decryption after the PRNG stage is given in Figure 9.
The subsequent code for restoring imports and their addresses (resolving function and library addresses), as well as changing attributes for virtual memory blocks (VirtualProtect calls), is identical to regular UPX (Figure 10 shows a snippet of packer code, Figure 11 shows regular UPX). Note also the distinctive, UPX-specific push and pop calls at the start and end, respectively, of the unpack function. After unpacking, control passes to the payload.
Payload
At the first stage, a mutex named YandexDisk is created, and the malware adds itself to startup via a registry key.
Next, the malware generates string requests to Yandex.Disk with the Authorization: OAuth parameter, to which the token for this account is concatenated (Figure 13). The token itself is stitched into the code. We found several keys belonging to three accounts: jethroweston, Poslova.Marian, upy4ndexdate.
After that, two lines are generated according to the pattern: pcname + /a.psd and pcname + /b.psd, for example: DESKTOP-IM5NM8R/a.psd, DESKTOP-IM5NM8R/b.psd.
The first request sent by the malware to C2 is a PUT to
(Figure 14 shows an example of generating it). It can be seen as an initializing request to be used to create a directory on Yandex.Disk (a working remote directory).https://cloud-api.yandex.net:443/v1/disk/resources?path=
If the connection is successful, the malware downloads a file (Figure 15) whose name consists of the following strings: the name generated in the previous step and the string modifier a.psd, which ends (is concatenated to the end of) the string name. For example,
https://cloud-api.yandex.net/v1/disk/resources/download?path=DESKTOP-IM5NM8R%2Fa.psd
The downloaded file contains a list of commands to be executed by the malware in order to retrieve basic information about the infected machine.
The commands are executed in a standard Windows shell (cmd.exe); the malware concatenates their results, forms them into a response, and sends them to Yandex.Disk as a b.psd file. Note that the result of the execution of each command is separated from the others by the line ==============\r\n (Figure 16 clearly shows the results of execution separated by this line).
Next, the malware switches to command execution mode. Malware-executed commands:
- DIR — retrieves the list of files in the directory;
- EXEC — executes the command (in fact, calls the WinExec function of the kernel32.dll library);
- SLEEP — calls the Sleep function with a parameter (0x3E8 multiplied by the passed constant);
- UPLOAD — uploads a file to Yandex.Disk;
- DOWNLOAD — downloads a file from Yandex.Disk.
All network communication is via cURL. In turn, data is transferred in JSON format, so the nlohmann/json, library is used to handle it; both libraries are statically compiled with the project.
Second YaRAT modification
Also found were a number of samples covered by VMProtect and not packed with the packer described above. A distinctive feature of all the samples is that only DllEntryPoint is covered by the protector, while the exports, which contain the main functionality, were not virtualized (except for some WinAPI calls).
Another distinguishing feature of such malware samples is the Blowfish-encrypted token with a key embedded in the code.
Despite the virtualized API calls, the application lends itself to static analysis and has a functionality quite similar to the one discussed above. The names of the built-in commands have not changed, and some commands may be missing.
As in the previous case, communication is via cURL; the same library is used to process JSON.
Stealer0x3401
The infection mechanism in this case is identical to the one examined in in our report: the legitimate binary file dot1xtray.exe downloads the malicious msvcr110.dll. In this instance, the __crtGetShowWindowMode export was malicious.
In the first step, the malware checks the name of the running process, which should not be qip.exe, aim.exe, or icq.exe. Otherwise, control will not pass to the main functionality.
Next, the address of the C2 server is decrypted (Figure 18). This algorithm is clearly identical to the one discussed in the previous report. Both the encryption key and the format of its location remained unchanged.
Next, the malware harvests the necessary information about the system by group. A list of these groups is shown in Figure 20 Note that this list is highly detailed and we have not seen such a list before. What's more, earlier tools used by the group collected other data. The fact that the malware contains lines in Russian is also curious (Figure 19).
All collected data is RC4-encrypted and Base64-encoded before being sent. In contrast to what we saw earlier, an encryption key is generated for each new run; the key generation algorithm is as follows (Figure 21): based on the current time, 16 pseudo-random numbers of qword type are generated (the loop adds 64-bit numbers up to the specified address; the difference between them is 128 bytes; accordingly, 16 qword values are obtained as per the data type), to which the standard key expansion procedure for RC4 is then applied. After that, the collected data is encrypted using the expanded key.
When transmitting encrypted data, the encryption key is not sent in cleartext; to obfuscate it, the previously unseen, so-called checksum procedure (Figure 22) is used for each qword value used in the key expansion procedure.
The procedure itself consists of two stages: generating a hash calculation table and directly calculating the result. The first stage involves cyclically computing the remainders from dividing the initializing constant (in this case 0x3401) using modulo 2 (until it becomes zero), that is, the number of rounds at each step of the checksum calculation will be identical.
At the second stage, the initial value is modified (_inputVal in Figure 22) in accordance with two variables initially equal to 0 and 1 (temValDword_1 and tempvalDword2 in Figure 22), from which at each step a value of type __int64 modulo 0x90c9bff is generated (result_x64Val in Figure 22). The constants themselves are also modified in each round.
As we see, the initial value is modified in each specific round as per the table of remainders created in the first stage. If the remainder is equal to 1, the hash, the variables themselves used in calculating the intermediate values, and the final value are all modified. Hence, a final value is generated for the specified 14 rounds (known in advance as regards modifying the initial value, since the table for all rounds is identical).
The generated hash for each of the qword components of the encryption key, the malware transmits to the server side.
Thus, the structure describing the encoded data is fairly simple:
struct Message{ QWORD key[16]; // hash array of qword components of the RC4 key char encrData[sizeOfData]; };
The generated data is Base64-encoded, after which it is prepended with the data= string and transmitted in this form to the server (Figure 23).
The malware sends the generated data to the C2 server ramblercloud[.]com, which is disguised as a legitimate Rambler cloud drive, but is not.
Attribution
While examining a document that used Template Injection (see the "Analyzing malicious documents" section) and infected the system when run, we detected traffic described by us in our previous report (see Figure 24).
After infecting the system, the malware exchanges data with C2, then executes commands from it.
Analysis of the unpacked sample revealed similarities with the samples we found earlier. In particular, the names of RTTI objects (including the names of the vtbl tables used for communication with C2) turned out to be identical, as did the functionality of both applications. No changes to the architecture, executable commands, or packet generation methods were identified, nor had the traffic encryption key embedded in the program code been modified. The sole difference between the malware samples is the partial virtualization of API calls inside the protected application (which is typical for any program covered by VMProtect). A snippet of the function for processing commands from the server is given in Figure 25.
Also unchanged are the service strings and format strings used to generate packages and data structures within the application, the names of the APIs used, and the order in which they are called.
Analysis of various malicious components revealed a characteristic sign that points to a single code base. In all cases, the malware harvested information about network adapters, and the function code and call sequence were identical: a call to GetAdaptersInfo, then retrieval of the value of the NetCfgInstanceId and Characteristics keys in the SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325- 11CE-BFC1-08002BE10318} registry hive.
These calls by themselves are quite standard; that said, we found no other examples of using this technique.
The code generated by the compiler was also identical, snippets of which (see Figure 26) we found in all unpacked malware components used in the campaign.
Confirms our assumption that this malware belongs to the APT31 group.
All the malicious components we detected can be divided into several groups:
- Documents with the same stub;
- Source documents have the same Author field;
- Malicious components have unique (within the scope of our coverage) code snippets that we have not seen elsewhere;
- Malware uses a cloud service in the role of C2.
The first point of interest is the external similarity between the stub in the documents that we attributed to the APT31 group above and the stub in one of the documents that extracted malicious components interacting with Yandex.Disk. The second is the identical code for retrieving information about network adapters that we encountered in both the attributed tools and in the tools described in this report.
Of particular note is the malware that harvested information about the infected system. This malicious component contains code we saw in the previous report on APT31 activity, with the code itself identical to that which was presented there. This malware additionally installed in the system a document with the Author field that we saw in other detected malware.
This malware thus acts as a linchpin for all the malicious components discussed above.
Having analyzed the above-mentioned tools, we can assign the malware samples studied to one group with a high degree of certainty. And given the use of cloud services as C2 servers (in this case, Yandex.Disk), which this group had already weaponized (previously it used Dropbox), we can assume that a single code base was used to write the malicious components.
The similar infection and persistence techniques, the numerous intersections within the code implementation framework, and the artifacts of the compilation tools used all strongly suggest that the group may continue its attacks on organizations in Russia.
Authors: Denis Kuvshinov, Daniil Koloskov, PT ESC
Indicators of compromise (IoC)
File indicators
Name | MD5 | SHA-1 | SHA-256 |
msvcr100.dll | 5897e67e491a9d8143f6d45803bc8ac8 | d91ffc6d48f79e0b55918fb73365b9fca37c9efa | 8148aeef6995c99c6f93ebce65b60bf57109914c45aa86d26a5cdc6ad8bba634 |
- | 91965ee08504eeb01e76e17007497852 | fd05e69d1f094b3a28bb5ae2a936607aa0db3866 | d7c1668c903a92f20bdeaee0f6e94b2ef3fefd700ca8daa4c4ff34a26f1323af |
WTSAPI32.dll | 0c1e1fd94383efc5a3de8f0117c154b2 | 3785d9c4bdf6812f753d93b70781d3db68141ce7 | aee1bf1f7e70f5cbd34a59b312573a6c7e34b1e412e4518a55a5b14af2102063 |
Анкета по результатам тестирования.doc | 85f8bfb3b859a35e342e35d7c35e8746 | ff5e78218198dd5ca5dc2eb46ec8afdd1b6260e9 | a56003dc199224113e9c85b0edb2197d4a4af91b15e7d0710873e2ef848c3221 |
О заседании.doc | 0c993a406be04b806222a130fb5a18e8 | 49307f1091251dd7a498cf69d0465ddd59859cf8 | 256d3065de2345a6beff9458ad0b519bed8363ac0b984247768bd788e633e371 |
WINHTTP.dll | dfaa28a53310a43031e406ff927a6866 | c694e99f8690114c77a6099856d61a3cd4cd814d | 4a5e9ab0e65e08ceb2adb2d150abb620684e98d79483b6c9f786c56c95fea573 |
Справка.doc | 0c4540f659d3942a28f158bce7be1143 | d1cc0f861f162dfbf9df1493fe861d02b80483f6 | 37e259d6564071807b7b4266ed1dd8bf2059f3e7f438b8487dd0149e5e0487ec |
msvcr110.dll | 1d65ef16d1f161ae3faa5ed7896734cd | 144493b13df06bab3f290b260b997b71164a25f7 | 0a5fb4a480b1748dc7f963a491a9aa32ff8c8fed01bea0cfd250a5ef01654eb3 |
payload_1.bin | 176d11c9bafac6153f728d8afb692f6f | ef0f61c32a3ae2494000f36a700a151c8b10c134 | ea9429fa66ba14b99ff756b8497ccbd3403437d4150eaed6c5c0fe4a3cdf78a8 |
5ehn6vctt.dll | 5897e67e491a9d8143f6d45803bc8ac8 | d91ffc6d48f79e0b55918fb73365b9fca37c9efa | 8148aeef6995c99c6f93ebce65b60bf57109914c45aa86d26a5cdc6ad8bba634 |
– | 50eb199e188594a42262a5bbea260470 | af33573bc8e507875acdb3db52bcfea13bb1286e | 0afeef5a4ac1b0bc778e66a1420587697dbfdb87d74a0b935db69b7d804089c4 |
– | c89eaa7f40fc75f9a34e0f0a3b59b88b | f3c600ba1d1d0cb1f3383805dbcac19e9423bdcb | 98b5cfa14dd805e1172b36415c71730fa3454ffbaababc7d4c7b1fcfb47dfbd7 |
WTSAPI32.dll | 0c1e1fd94383efc5a3de8f0117c154b2 | 3785d9c4bdf6812f753d93b70781d3db68141ce7 | aee1bf1f7e70f5cbd34a59b312573a6c7e34b1e412e4518a55a5b14af2102063 |
WTSAPI32.dll | 640e6ecad629bd33c09ccec52f4aa6da | 584fd63ab925c532cf40818886487714b3de317e | add70042c65cd683925936aa04c79a8644e40dd93aa5ff1913bf533457daccf3 |
libcef.dll | 11010e139010697a94a8feb3704519f9 | 52999153cc7d3a3771a8ee9b8e55f913829109a7 | c2b769f40b1ec2ee57e4d36f545d6de93bbd54d2514347fb54cc20b1bfb9ca97 |
Приложение 1 к исх письмо по списку рассылки.pdf | 099c7d85d0d26a31469465d333329778 | d25a68289fc1268d7c548787373a6235895716fb | c3382ebff9dcd0e8776820f70faaa8cd4c0c93578444e5cfe3720e0b232fa6d8 |
материал-20220210.exe | 8b4c1f0ff1cee413f5f2999fa21f94f9 | 97e19f67a8d6af78c181f05198aa7d200b243ea5 | f49999f1d7327921e63097b4f90f437a0122361676b73a81f0ff2b681b1dd8de |
Network indicators
portal.super-encrypt.com
super-encrypt.com
portal.intranet-rsnet.com
intranet-rsnet.com
p1.offline-microsoft.com
offline-microsoft.com
cdn.microsoft-official.com
microsoft-official.com
ramblercloud.com
yandexpro.net
MITRE TTPs
ID | Name | Description |
Initial Access |
||
T1566 | Phishing | APT31 sends phishing messages to gain access to victim systems |
Execution |
||
T1204 | User Execution | APT31 sends MS Word documents containing malicious components |
Resource Development |
||
T1587.001 | Malware | APT31 develops malware and malware components that can be used during targeting |
T1587.002 | Develop Capabilities: Code Signing Certificates | APT31 uses code signing to sign their malware and tools |
Persistence |
||
T1547.001 | Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder | APT31 achieves persistence by adding a program to a Registry run key |
T1574 | Hijack Execution Flow | APT31 executes their own malicious payloads by hijacking the way operating systems run programs |
Defense Evasion |
||
T1140 | Deobfuscate/Decode Files or Information | APT31 uses mechanisms to decode or deobfuscate information |
T1036 | Masquerading | APT31 manipulates features of their artifacts to make them appear legitimate to users |
T1112 | Modify Registry | APT31 team uses the Windows registry for persistence |
T1027 | Obfuscated Files or Information | APT31 uses encryption to make it difficult to detect or analyze an executable file |
Collection |
||
T1560 | Archive Collected Data | APT31 tools encrypted the collected data before sending it to the servers |
Command and Control |
||
T1001 | Data Obfuscation | APT31 obfuscates command and control traffic to make it more difficult to detect |
T1095 | Non-Application Layer Protocol | APT31 group used SSL for data transmission |
T1573.001 | Encrypted Channel: Symmetric Cryptography | APT31 used symmetric encryption algorithms to hide transmitted data |
T1132.001 | Data Encoding: Standard Encoding | APT31 group used RC4 and Base64 to hide transmitted data |
T1132.002 | Data Encoding: Non-Standard Encoding | The APT31 group used custom encryption key obfuscation algorithms as well as payload encryption |
T1102 | Web Service | APT31 group used Yandex.Disk as C&C |
Exfiltration |
||
T1020 | Automated Exfiltration | APT31 uses automatic exfiltration of stolen files |
T1041 | Exfiltration Over C2 Channel | APT31 uses C&C channel to exfiltrate data |