In August 2024, our team identified a new crimeware bundle, which we named “SteelFox”. Delivered via sophisticated execution chains including shellcoding, this threat abuses Windows services and drivers. It spreads via forums posts, torrent trackers and blogs, imitating popular software like Foxit PDF Editor and AutoCAD. It also uses stealer malware to extract the victim’s credit card data as well as details about the infected device.
This report in a nutshell:
Kaspersky’s products detect this threat as HEUR:Trojan.Win64.SteelFox.gen, Trojan.Win64.SteelFox.*.
In August 2024, we stumbled upon a massive infection caused by an unknown bundle consisting of miner and stealer malware. During our investigation, we found out that the campaign started in February 2023. Although the stealer has not evolved significantly since then, it is being gradually changed to avoid detection. No functional changes are being added, but the author updates all the required dependencies.
Our investigation has led us to the fact that SteelFox’s initial attack vector consists of several various publications on forums and torrent trackers. These posts refer to the SteelFox dropper as an efficient way to activate a legitimate software product for free. We’ve seen the dropper pretend to be a crack for Foxit PDF Editor, JetBrains and AutoCAD. While these droppers do have the advertised functionality, they also deliver sophisticated malware right onto the user’s computer.
In this research, we describe the sample imitating an activator for Foxit PDF Editor. The initial stage of the SteelFox campaign is an AMD64 executable under the name foxitcrack.exe with a large .rdata section. Judging by the high entropy, it seems that the file is packed. At the startup the program welcomes us with a GUI asking to choose the Foxit PDF Editor installation path.
Because Foxit’s installation directory resides in the “Program Files” folder, FoxitCrack asks for administrator access, which will be used for malicious purposes later.
The execution chain looks legitimate until the moment the files are unpacked. Prior to a legitimate function, a malicious one is inserted that is responsible for dropping malicious code onto the target user’s system.
First, the second stage (the dropped malicious code) is decrypted with the AES-128 algorithm. Its parameters are also encrypted — they are decrypted once dropped by the first stage. The encryption scheme looks like this.
// Sbox decryption for (int i = 0; i < 256; i++) { SBox[i] = enc_Sbox[i + 16] ^ enc_SBox[i % 16]; } for (int i = 0 i < 8; i++) { key[i] = enc_key[i + 8] ^ enc_key[i % 8]; iv[i] = enc_iv[i + 8] ^ enc_iv[i % 8]; } |
AES-128 is implemented via vector SIMD instructions, thus requiring the payload to be divided into 16-byte blocks.
In later versions of the dropper, the actor implemented the same algorithm but used the AES-NI instruction-set extension. Since they operate with 16-byte blocks, it implies that the requirement for the payload size alignment remains in place.
After that, the embedded payload, which is, in fact, a PE64 executable, is modified to avoid detection. Linking timestamps are overwritten with a random date in the range between May and December 2022, along with the linker version. Random junk data is also inserted into the .rdata section to avoid hash detection. This is accomplished with an embedded PE parser.
The dropped PE is written into one of the three paths. The exact path depends on the dropper sample:
The parameters of the malicious service are initialized as follows:
After this, the second-stage loader creates a service which writes itself to the autostart to persist in the system and remain active through reboots.
This service is started from svchost.exe as a regular Windows service. First, it gets the full name of the current executable and compares it against service binary names to check whether the loader was started as a service. If the check is successfully passed, the service lists all running services (with a SERVICE_ACTIVE state), getting their executable paths and descriptions. This is quite a peculiar way to check against a debugger because if the binary is not started as a service, the loader will throw an exception and quit. This algorithm is obfuscated in the loader code, but after deobfuscating it resembles the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
vector<QUERY_SERVICE_INFOW> vec; get_services_list(vec); std::wstring serv_name; GetModuleFileNameW(0, exec_name, 256); for (auto service : vec) { SC_HANDLE hService = open_service(service.lpServiceName); LPCWSTR *bin_name = get_service_bin_path(hService, service.lpServiceName); if (!wstrcmp(exec_name, bin_name) { serv_name = service.lpServiceName; break; } } if (serv_name.empty()) { throw std::system_error; } |
If these checks are passed, the malware creates a function table, which allows the attacker to perform decryption and create shellcodes. It also contains a random number generator along with placeholders.
The execution flow now proceeds to the StartServiceCtrlDispatcherW function. It registers a dispatcher with a function that is responsible for decryption and injection. It controls the state of the service, handles the service restart and shutdown signals, and so on.
Before the actual payload is executed, the malware triggers an unusual persistence mechanism: a small but rather important step. This stage launches the AppInfo service and is then loaded inside that. This makes any user actions against this loader impossible because even copying this sample requires NT\SYSTEM privileges.
The target DLL is loaded via a malicious shellcode and encrypted with AES-128 in the same way as described earlier in the initial stage. The decryption of later versions is also implemented with AES-NI instructions.
The malicious shellcode is loaded in three fundamental steps. First, it creates an array of addresses to WinAPI functions that will be executed within the shellcode.
Then the payload is decrypted with a rather simple XOR-based algorithm. After decryption, the shellcode is executed with hardcoded parameters.
The shellcode is a basic loader: it utilizes provided imported WinAPIs to allocate memory for loading the final stage and to access library functions. This shellcode does not implement any protection against debugging. It remains just a basic PE loader that proceeds to the final stage.
At the beginning, this stage (DLL) creates a mutex with a randomly generated name because its network communication heavily relies on multithreading and asynchronous network I/O. After that, it performs an important task: creating a service with a WinRing0.sys driver running inside. This service is accompanied by a pipe named \\.\WinRing0_1_2_0 which allows the process to communicate with the driver. This is quite an old driver, vulnerable to CVE-2020-14979 and CVE-2021-41285, and allowing the actor to elevate privileges to NT\SYSTEM as soon as the direct unchecked communication with the driver is allowed and the attacker controls input forwarded to the driver. This driver is also a component of the XMRig miner, so it is utilized for mining purposes. The communication with the driver is performed in a separate thread.
After initializing the driver, the sample launches the miner. This represents a modified executable of XMRig with junk code fillers. It connects to a mining pool with hardcoded credentials.
The XMRig component is downloaded from one of the repositories at hxxps://github[.]com/cppdev-123. It seems to get updates occasionally — we assume this is done in order to avoid detection of older versions.
After that, the malware resolves the IP address behind the ankjdans[.]xyz domain which serves as a C2 server. Although the domain is hardcoded, switching IPs behind it helps the attacker remain undetected. SteelFox resolves this via Google Public DNS and DNS over HTTPS (DoH). This allows the attacker to hide the domain resolution.
After a successful IP resolution, the malware connects to its C2 server via TLSv1.3. This I/O model utilizes libraries like Boost.Asio and wolfSSL, which allows the attacker to implement end-to-end TLSv1.3 communication.
Unlike v1.2, TLS v1.3 generates a session secret from a preselected private key during the handshake stage. In this case, the shared secret is generated with a Windows cryptographically secure random number generator. Furthermore, SteelFox has fully implemented SSL pinning to ensure SSL communication can’t be wiretapped. Interestingly enough, SSL pinning is only enabled for C2 server communication.
When a connection is established, the stealer comes into play. This component can collect a large list of end users’ parameters. It enumerates browsers on the victim’s device and then compares them against the following list of browsers:
It extracts cookies, credit card data, browsing history and the list of visited places, the latter only from Mozilla Firefox. This is done with an embedded copy of SQLite3. Because the service runs as NT\SYSTEM, it calls the ImpersonateLoggedOnUser API to get the security context for creating an SQL dump later.
The full list of extracted data is provided below.
Type of data | Details |
Browser data | Cookies, credit cards, location, search history |
Software | Installed software, antivirus solutions, running services, installed addons |
System info | Build date (if possible), version, revision, installation date |
Network info | Wireless interfaces, networks and passwords (extracted as plaintext) |
SIM | SIM-card data (if applicable) |
Drives | Drive names and types (external, removable, etc.), drive free space |
Environment | Environment variables dump |
Time | Local time, timezone |
User info | Username, startup info, password, system locale, remote accounts info (through the NetUserEnum WinAPI) |
RDP | Sessions and session info (through the WTSQuerySessionInformationW WinAPI) |
Desktop | Icons of installed and running software |
Processes | Memory usage and pages range |
Data is then combined into one large JSON that is sent to C2. The communication diagram is as follows.
This campaign does not target any individuals or specific organizations. Instead, it operates on a larger scale, infecting everyone who stumbles upon the compromised software. At the time of this research, our security solutions had detected this threat more than 11,000 times. Users of various popular applications, such as AutoCAD, JetBrains and Foxit, are targeted. We have detected victims of this campaign worldwide, with most of the affected users in Brazil, China, Russia, Mexico, UAE, Egypt, Algeria, Vietnam, India and Sri Lanka.
TOP 10 countries targeted by SteelFox, August–September, 2024 (download)
For this particular campaign, no attribution can be given. Posts with links to activators were either made by compromised accounts or by inexperienced users who were not aware of the threats they were spreading. This campaign was highly active on the Chinese platform Baidu and Russian torrent trackers.
SteelFox has emerged recently, and it is a full-featured crimeware bundle. It is capable of stealing various user data that might be of interest to the actors behind this campaign. Highly sophisticated usage of modern C++ combined with external libraries grant this malware formidable power. Usage of TLSv1.3 and SSL pinning ensures secure communication and harvesting of sensitive data.
SteelFox does not target any particular organizations or people. Instead, it acts on a mass scale, extracting every bit of data that can be processed later. To ensure protection from threats like this, install applications from official sources and use a reliable security solution that prevents downloading infected software.
Note: The indicators in this section are valid as at the time of publication.
File Hashes
Payload
fb94950342360aa1656805f6dc23a1a0
Loader
Dropper
File paths
C:\Program Files (x86)\Foxit Software\Foxit PDF Editor\plugins\FoxitPDFEditorUpdateService.exe
C:\Program Files (x86)\Common Files\Adobe\AdobeGCClient\AGSService.exe
C:\Program Files\Autodesk\AdODIS\V1\Setup\lpsad.exe
PDB paths
d:\hotproject\winring0\source\dll\sys\lib\amd64\WinRing0.pdb
Domains and IPs
hxxps://ankjdans[.]xyz
205.185.115[.]5
Malicious URLs
hxxps://github[.]com/DavidNguyen67/CrackJetbrains
hxxps://github[.]com/TrungGa123/Active-all-app-Jetbrains/
hxxps://github[.]com/tranquanghuy-09/activate-intellij-idea-ultimate/
hxxps://github[.]com/TaronSargsyan123/ScaraSimulation
hxxps://raw.githubusercontent[.]com/tranquanghuy-09/activate-intellij-idea-ultimate/main/jetbrains-activator.exe
hxxps://raw.githubusercontent[.]com/TaronSargsyan123/ScaraSimulation/main/jetbrains-activator.exe
hxxps://raw.githubusercontent[.]com/TrungGa123/Active-all-app-Jetbrains/main/jetbrains-activator.exe
hxxps://raw.githubusercontent[.]com/DavidNguyen67/CrackJetbrains/main/jetbrains-activator.exe
hxxps://www.cloudstaymoon[.]com/2024/05/06/tools-1
hxxps://squarecircle[.]ru/Intelij/jetbrains-activator.exe
hxxps://drive.google[.]com/file/d/1bhDBVMywFg2551oMmPO3_5VaeYnj7pe5/view?usp=sharing
hxxps://github[.]com/cppdev-123