We recently found an active campaign that uses a fake employment pretext targeting Eastern Europeans in the cryptocurrency industry to install an information stealer. In this campaign, the suspected Russian threat actors use several highly obfuscated and under-development custom loaders to infect those involved in the cryptocurrency industry with the Enigma Stealer (detected as TrojanSpy.MSIL.ENIGMASTEALER.YXDBC), a modified version of the Stealerium information stealer. In addition to these loaders, the attacker also exploits CVE-2015-2291, an Intel driver vulnerability, to load a malicious driver designed to reduce the token integrity of Microsoft Defender.
Stealerium, the original information stealer which serves as the base for Enigma Stealer, is an open-source project written in C# and markets itself as a stealer, clipper, and keylogger with logging capabilities using the Telegram API. Security teams and individual users are advised to continuously update the security solutions of their systems and remain vigilant against threat actors who perform social engineering via job opportunity or salary increase-related lures.
Attack Chain
Using fake cryptocurrency interviews to lure victims
The infection chain starts with a malicious RAR archive — in this instance, contract.rar (SHA256: 658725fb5e75ebbcb03bc46d44f048a0f145367eff66c8a1a9dc84eef777a9cc) — which is distributed to victims via phishing attempts or through social media. The archive contains the files, Interview questions.txt, and Interview conditions.word.exe.
These files set up the pretext for a fake cryptocurrency role or job opening. One file, Interview questions.txt (SHA256: 3a1eb6fabf45d18869de4ffd773ae82949ef80f89105e5f96505de810653ed73) contains sample interview questions written in Cyrillic. This serves to further legitimize the package in the eyes of the victim and draw attention away from the malicious binary.
The other file Interview conditions.word.exe (SHA256: 03b9d7296b01e8f3fb3d12c4d80fe8a1bb0ab2fd76f33c5ce11b40729b75fb23) contains the first stage Enigma loader. This file, which also masquerades as a legitimate word document, is designed to lure unsuspecting victims into executing the loader. Once executed, the Enigma loader begins the registration and downloading of the second-stage payload.
Analysis of the Enigma infrastructure
Enigma uses two servers in its operation. The first utilizes Telegram for delivering payloads, sending commands, and receiving the payload heartbeat. The second server 193[.]56[.]146[.]29 is used for DevOps and logging purposes. At each stage the payload sends its execution log to the logging server. Since this malware is under continuous development the attacker potentially uses the logging server to improve malware performance. We have also identified the Amadey C2 panel on 193[.]56[.]146[.]29 which has only one sample (95b4de74daadf79f0e0eef7735ce80bc) communicating with it.
Amadey is a popular botnet that is sold on Russian speaking forums, but its source code has been leaked online. Amadey offers threat actors polling and reconnaissance services.
This server has a unique Linux distribution only referenced in Russian Linux forums.
The default time zone on this server is set to Europe/Moscow. This server registers a newly infected host when Interview conditions.word.exe is executed by the victim.
Stage 1: EnigmaDownloader_s001
MD5 | 1693D0A858B8FF3B83852C185880E459 |
SHA-1 | 5F1536F573D9BFEF21A4E15273B5A9852D3D81F1 |
SHA-256 | 03B9D7296B01E8F3FB3D12C4D80FE8A1BB0AB2FD76F33C5CE11B40729B75FB23 |
File size | 367.00 KB (375808 bytes) |
The initial stage of Enigma, Interview conditions.word.exe, is a downloader written in C++. Its primary objective is to download, deobfuscate, decompress, and launch the secondary stage payload. The malware incorporates multiple tactics to avoid detection and complicate reverse engineering, such as API hashing, string encryption, and irrelevant code.
Before delving into the analysis of "EnigmaDownloader_s001," let's first examine how the malware decrypts strings and resolves hashed Windows APIs. By understanding this, we can implement an automated system to help us retrieve encrypted data and streamline the analysis process. Please be advised that to enhance code legibility, we have substituted all hashes with the corresponding function names.
API hashing is a technique employed by malware to conceal the utilization of potentially suspicious APIs (functions) from static detection. This technique helps the malware disguise its activities and evade detection.
It involves replacing the human-readable names of functions (such as "CreateMutexW") with a hash value, such as 0x0FD43765A. The hash value is then used in the code to call the corresponding API function, rather than using the human-readable name. The purpose of this technique is to make the process of understanding the code more time-consuming and difficult.
For API Hashing the EnigmaDownloader_s001 uses the following custom MurmurHash:
The malware employs dynamic API resolving to conceal its API imports and make static analysis more difficult. This technique involves storing the names or hashes of the APIs needed, then importing them dynamically at runtime.
The Windows API offers LoadLibrary and GetProcAddress functions to facilitate this. LoadLibrary accepts the name of a DLL and returns a handle, which is then passed to GetProcAddress along with a function name to obtain a pointer to that function. To further evade detection, the malware author even implemented their own custom version of GetProcAddress to retrieve the address of functions such as LoadLibrary and others. The use of standard methods like GetProcAddress and LoadLibrary might raise a red flag, so the custom implementation helps to avoid detection.
The following is a list of API hash values along with the names of functions that have been used in this sample (Please note that the hash value might be different in other variants since the malware author changed some of the constant values in the hash generator function).
- 0xE04A219 : kernel32_HeapCreate
0xA1ADA36 : kernel32_lstrcpyA
0x5097BB4 : kernel32_RegOpenKeyExA
0x750EFAB : kernel32_GetLastError
0x4CB039A : kernel32_RegQueryValueExA
0xAAF4498 : kernel32_RegCloseKey
0xFAD2A34 : kernel32_lstrcmpiA
0x11A198F : combase_CoCreateGuid
0xE94A809 : kernel32_RtlZeroMemory
0x6A6A154 : kernel32_lstrcatA
0x8150471 : ntdll_RtlAllocateHeap
0x4CF4539 : user32_wvsprintfW
0x663555F : kernel32_WideCharToMultiByte
0x59CADCE : ntdll_RtlFreeHeap
0x1CE543C : cabinet_CloseDecompressor
0x11CF0A2 : wininet_InternetGetConnectedState
0x675C7B2 : kernel32_Sleep
0xDC75FF2 : wininet_InternetCheckConnectionA
0x5CC35B1 : wininet_InternetSetOptionA
0xF9E8859 : wininet_InternetOpenA
0x6F05A9E : wininet_InternetConnectA
0xBAEECD9 : wininet_HttpOpenRequestA
0xAD9A77C : wininet_HttpSendRequestA
0x835FA71 : wininet_HttpQueryInfoA
0xBFA9532 : wininet_InternetReadFile
0x99D029C : wininet_InternetCloseHandle
0x8DABD38 : kernel32_GetFileAttributesW
0x44E1C18 : kernel32_DeleteFileW
0xAB69596 : kernel32_CreateFileW
0x2CF38A1 : kernel32_WriteFile
0x1CE43DE : kernel32_CloseHandle
0x548C5A4 : Rpcrt4_RpcStringBindingComposeW
0x7B0F79F : Rpcrt4_RpcBindingFromStringBindingW
0x69A2B62 : Rpcrt4_RpcStringFreeW
0xD2CD112 : advapi32_CreateWellKnownSid
0xEFBC2E9 : kernel32_LocalFree
0x60EDB01 : Rpcrt4_RpcBindingFree
0x7A7DAA0 : Rpcrt4_RpcAsyncInitializeHandle
0xB3F16FA : kernel32_CreateEventW
0x1C23B4F : Rpcrt4_NdrAsyncClientCall
0x8C1F37 : kernel32_WaitForSingleObject
0x7831640 : Rpcrt4_RpcRaiseException
0xF2FCCFE : Rpcrt4_RpcAsyncCompleteCall
0x816F545 : kernel32_SetLastError
0xFBE2D99 : oleaut32_SysAllocString
0x393ACB : oleaut32_SysFreeString
0xC9FEF5F : kernel32_ExpandEnvironmentStringsW
0x74D51D3 : kernel32_CreateProcessW
0xCDE9EC27 : wininet_HttpWebSocketClose
0x80C8449 : kernel32_TerminateProcess
0x418B4E7E : wininet_AppCacheCheckManifest
0x44E65EB : kernel32_WaitForDebugEvent
0x81C3F46 : kernel32_ContinueDebugEvent
0x1FB9EB2 : kernel32_LoadLibraryW
0x1071970 : kernel32_GetProcAddress
0xDAE6C9B : combase_CoInitializeEx
0xFD43765 : kernel32_CreateMutexW
0x73861029 : kernel32_BasepSetFileEncryptionCompression
0xA3FE987 : advapi32_RegDeleteKeyW
0x1CA6703 : advapi32_RegCreateKeyA
0x24EBD39 : kernel32_lstrlenA
0x69F38C6 : kernel32_RegSetValueExA
0xC2D33DC : ntdll_RtlGetVersion
0xBD5D03A : kernel32_GetNativeSystemInfo
0x10BEDD60 : wininet_CreateMD5SSOHash
To resolve the API hash, the malware first passes two arguments to the "mw_resolveAPI" function. The first argument is the specific library name index number (in this case 0xA = Kernel32.dll), while the second argument is the export function name hashed value (which, in this example, is 0xFD43765A)
The mw_resolveAPI function first finds the specific index, jumps to it, and decrypts the corresponding library name value as shown in the bottom image of Figure 9.
The following is the list of decrypted library names:
- WinInet.dll
- userenv.dll
- psapi.dll
- netapi32.dll
- mpr.dll
- wtsapi32.dll
- api-ms-win-core-processthreads-l1-1-0.dll
- ntoskrnl.exe
- Rpcrt4.dll
- User32.dll
- api-ms-win-core-com-l1-1-0.dll
- Cabinet.dll
- shell32.dll
- OleAut32.dll
- Ole32.dll
- ntdll.dll
- mscoree.dll
- kernel32.dll
- advapi32.dll
The library name and export function name hashed value is then passed to GetExportAddressByHash, which is responsible for opening the handle to the library, creating a hash for each export function name, and comparing it with the passed argument. Once the match is found, the malware returns the function address and calls it.
The code snippet in Figure 11 demonstrates how mw_GetExportAddressByHash resolves the given API hash and retrieves the address of an exported function. The techniques used to decrypt strings and resolve API hashes in both the stage 1 and stage 2 payloads are identical.
With an understanding of this process, we can then proceed with our analysis.
Upon execution, the malware creates the mutual exclusion object (mutex) to mark its presence in the system and retrieves the MachineGuid of the infected system from the SOFTWARE\Microsoft\Cryptography\MachineGuid registry key, which it uses as a unique identifier to register the system with its C&C server and track its infection.
It then deletes the HKCU\SOFTWARE\Intel registry key and recreates it with two values, HWID and ID, as shown in Figure 13.
It then collects information about the .NET Framework Setup on the infected system and sends it to its C&C server as shown in Figure 14.
There are two C&C servers that were used in this attack chain. The first one ,193[.]56[.]146[.]29, is used to send program execution DEBUG and Telegram to deliver payloads and send commands.
To download the next stage payload, the malware first sends a request to the attacker-controlled Telegram channel https://api[.]telegram[.]org/bot{token}/getFile to obtain the file_path. This approach allows the attacker to continuously update and eliminates reliance on fixed file names.
Note that in this case, the next stage payload was file_17.pack. However, this file and other stage names were changed multiple times during our investigation.
Upon obtaining the file_path, the malware then sends a request to download the next stage binary file (shown in Figure 17)
If the file's download, deobfuscation, and decompression are successful, the malware sends the message "bot getted" to the debug server.
To decompress the payload, the malware uses Microsoft Cabinet's Compressapi with the compression algorithm ("COMPRESS_RAW | COMPRESS_ALGORITHM_LZMS"). The code snippet in Figure 20 demonstrates how the malware downloads, deobfuscates, and decompresses file_17.pack (UpdateTask.dll).
Before executing the payload, the malware attempts to elevate its privileges by executing the mw_UAC_bypass function, which is part of an open-source project. This technique, Calling Local Windows RPC Servers from .NET (which was unveiled in 2019 by Project Zero), allows a user to bypass user account control (UAC) using only two remote procedure call (RPC) requests instead of DLL hijacking.
The malware requires elevated privileges for the subsequent stage payload, which involves loading the malicious driver by exploiting CVE-2015-2291.
Finally, the malware executes an export function called "Entry" from UpdateTask.dll via rundll32.exe as shown in Figure 23.
Stage 2: EnigmaDownloader_s002
MD5 | |
SHA-1 | |
SHA-256 | |
File size |
The second stage payload, UpdatTask.dll, is a dynamic-link library (DLL) written in C++ that comprises two export functions (DllEntryPoint and Entry). The malicious code is executed in the Entry export function, which is triggered by the first stage routine. The primary objective of this malware is to disable Microsoft Defender by deploying a malicious kernel mode driver (“bring your own vulnerable driver” or BYOVD method) via exploiting a vulnerable Intel driver (CVE-2015-2291) and then downloading and executing the third-stage payload.
Please note that the first, second, and third-stage payloads all obtain the infected system's MachineGuid at the start and use it to identify the machine in debug message network traffic, enabling the adversary to track the infected system's malware execution state.
Upon execution, the malware creates the mutex to mark its presence on the system and retrieves the MachineGuid of the infected system from the "SOFTWARE\Microsoft\Cryptography\MachineGuid" registry key.
Next, the malware will determine if it is running as an account with administrator privileges or simply as a regular user using the GetTokenInformation API. If the malware fails to obtain elevated privileges, it will bypass the disablement of Windows Defender and proceed to download and execute the next stage of its attack.
If the process successfully obtains elevated privileges, it proceeds to drop the files shown in Figure 26.
Name | iQVW64.SYS (CVE-2015-2291) |
Description | Vulnerable Intel driver, used for kernel exploitation |
MD5 | 1898ceda3247213c084f43637ef163b3 |
SHA-1 | d04e5db5b6c848a29732bfd52029001f23c3da75 |
SHA-256 | 4429f32db1cc70567919d7d47b844a91cf1329a6cd116f582305f3b7b60cd60b |
Name | Driver.SYS |
Description | Malicious drivers reduce the token integrity of Microsoft defender (MsMpEng.exe) |
MD5 | 28ca7a21de60671f3b528a9e08a44e1c |
SHA-1 | 21F1CFD310633863BABAAFE7E5E892AE311B42F6 |
SHA-256 | D5B4C2C95D9610623E681301869B1643E4E2BF0ADCA42EAC5D4D773B024FA442 |
The malware uses an open-source project called KDMapper to manually map non-signed/self-signed drivers in memory by exploiting the iqvw64e.sys Intel driver. Testing on this has reportedly been conducted on Windows 10 version 1607 to Windows 11 version 22449.1. The functions intel_driver::Load() and kdmapper::MapDriver() are both responsible for achieving this task.
The following snippet demonstrates the debug message related to drive loading and installation:
The malware then establishes persistence on the targeted system by creating scheduled tasks.
Finally, the EnigmaDownloader_s002 downloads and executes the next-stage payload on the infected system. To achieve this task, it employs similar techniques as those used in the first stage — the only difference, in this case, is that the malware is executing a .NET Assembly from C++ in memory using the CLR (Common Language Runtime) hosting technique.
Stage 2.1: Enigma Driver analysis
MD5 | Driver.SYS |
SHA-1 | 28CA7A21DE60671F3B528A9E08A44E1C |
SHA-256 | 21F1CFD310633863BABAAFE7E5E892AE311B42F6 |
File size | D5B4C2C95D9610623E681301869B1643E4E2BF0ADCA42EAC5D4D773B024FA442 |
The driver's sole purpose is to patch the integrity level of the Microsoft defender (MsMpEng.exe) and forcibly reduce it from system to untrusted integrity. The reduction of the integrity level to untrusted impedes the process of accessing secure resources on the system for the victim, silently disabling it without terminating the process.
The code snippets in Figure 31 demonstrate how the malware performs these operations.
Stage 3: EnigmaDownloader_s003
The following table shows the details of Enigma.Bot.Net.exe.
MD5 | 50949ad2b39796411a4c7a88df0696c8 |
SHA-1 | 67a502395fc4193721c2cfc39e31be11e124e02c |
SHA-256 | 8dc192914e55cf9f90841098ab0349dbe31825996de99237f35a1aab6d7905bb |
File size | 10.50 KB (10752 bytes) |
EnigmaDownloader_s003 is a third-stage downloader written in C#. It is responsible for downloading, decompressing, and executing the final stealer payload on an infected system. The malware also accepts commands from a Telegram channel, though these commands may vary between variants.
stop
alive
runassembly
Upon launch, the malware sends a "Bot started" message to both the Debug server and the Telegram channel, indicating its successful execution.
It then sends a GET request to https://api[.]telegram[.]org/bot{token}/getUpdates to retrieve the command. Upon receiving the runassembly command, the malware downloads the next part of the final stage payload (file_19.pack), decompresses it using the GZipStream API, and executes it.
Stage 4: Enigma Stealer
MD5 | 4DC2D57D9DB430235B21D7FB735ADF36 |
SHA-1 | 98BF3080A85743AB933511D402E94D1BCEE0C545 |
SHA-256 | 4D2FB518C9E23C5C70E70095BA3B63580CAFC4B03F7E6DCE2931C54895F13B2C |
File size | 2954.75 KB (2954752 bytes) |
The final stage is the Enigma Stealer which, as we previously mentioned, is a modified version of an open-source information stealer project called Stealerium.
Upon execution, the malware initializes configuration and sets up its working directory.
The malware configuration is as follows:
public static string Version = "0.05.01";
public static string DebugMode = "0";
public static string Mutex = "6C0560CE-2E75-4BB4-A26E-F08592A1D56D";
public static string AntiAnalysis = "0";
public static string Autorun = "1";
public static string StartDelay = "0";
public static string WebcamScreenshot = "1";
public static string KeyloggerModule = "0";
public static string ClipperModule = "0";
public static string GrabberModule = "0";
public static string TelegramToken = "5894962737:AAHAFZnz2AkLAyHC0G-7S2je9JMWWLJHGsU";
public static string TelegramChatID = "5661436914";
It then starts to collect system information and steals user information, tokens, and passwords from various web browsers and applications such as Google Chrome, Microsoft Edge, Microsoft Outlook, Telegram, Signal, OpenVPN and others. It captures screenshots and extracts clipboard content and VPN configurations.
The collected information is then compressed and exfiltrated to the attacker via Telegram.
Figure 41 illustrates a sample of the network traffic generated by the malware.
It's worth mentioning that some strings, such as web browser paths and Geolocation API services URLs, are encrypted with the AES algorithm in cipher-block chaining (CBC) mode.
List of decrypted strings:
\Chromium\User Data\
\Google\Chrome\User Data\
\Google(x86)\Chrome\User Data\
\Opera Software\
\MapleStudio\ChromePlus\User Data\
\Iridium\User Data\
7Star\7Star\User Data
//CentBrowser\User Data
//Chedot\User Data
Vivaldi\User Data
Kometa\User Data
Elements Browser\User Data
Epic Privacy Browser\User Data
uCozMedia\Uran\User Data
Fenrir Inc\Sleipnir5\setting\modules\ChromiumViewer
CatalinaGroup\Citrio\User Data
Coowon\Coowon\User Data
liebao\User Data
QIP Surf\User Data
Orbitum\User Data
Comodo\Dragon\User Data
Amigo\User\User Data
Torch\User Data
Yandex\YandexBrowser\User Data
Comodo\User Data
360Browser\Browser\User Data
Maxthon3\User Data
K-Melon\User Data
CocCoc\Browser\User Data
BraveSoftware\Brave-Browser\User Data
Microsoft\Edge\User Data
http://ip-api.com/line/?fields=hosting/content/dam/trendmicro/global/en/research/23/enigma-stealer-targets-cryptocurrency-industry-with-fake-jobs/iocs-enigma-stealer-targets-cryptocurrency-industry-with-fake-jobs-tm.txt
https://api.mylnikov.org/geolocation/wifi?v=1.1&bssid=
https://discordapp.com/api/v6/users/@me
Conclusion
Similar to previous campaigns involving groups such as Lazarus, this campaign demonstrates a persistent and lucrative attack vector for various advanced persistent threat (APT) groups and threat actors. Through the use of employment lures, these actors can target individuals and organizations across the cryptocurrency and Web 3 sphere. Furthermore, this case highlights the evolving nature of modular malware that employ highly obfuscated and evasive techniques along with the utilization of continuous integration and continuous delivery (CI/CD) principles for continuous malware development.
Organizations can protect themselves by remaining vigilant against phishing attacks. Furthermore, individuals are advised to remain cautious of social media posts or phishing attempts that offer job opportunities unless they are sure of their legitimacy. Due to current economic conditions, threat actors can be expected to continue to heavily deploy employment lures to target those seeking employment.
Meanwhile, organizations should also consider cutting edge multilayered defensive strategy and comprehensive security solutions such as Trend Micro™ XDR that can detect, scan, and block malicious URLs across the modern threat landscape.
Indicators of Compromise (IOCs)
The indicators of compromise for this entry can be found here.