Investigating the resurgence of the Mexals campaign
Executive summary
Editorial and additional comments by Tricia Howard
Akamai Security Research has been tracking and analyzing the resurgence of Mexals, a likely Romanian based cryptojacking campaign.
The campaign has been active since at least 2020, and was previously covered in a report by Bitdefender in July 2021.
The newest wave of attacks and malware improvements seems to have started in October 2022. They are now calling themselves Diicot, which is also the name of the Romanian anti-terrorism and organized crime agency.
Akamai security researchers started analyzing the campaign following a malicious DNS detection at an Akamai customer. All affected Akamai customers were swiftly notified and proper countermeasures were taken.
The attackers use a long chain of payloads before eventually dropping a Monero cryptominer.
New capabilities include usage of a Secure Shell Protocol (SSH) worm module, increased reporting, better payload obfuscation, and a new LAN spreader module.
By analyzing the miner’s pool, we estimate the attackers have mined XMR coins worth approximately US$10,000.
We provide mitigation strategies, detection tools and a full indicators of compromise (IOC) repository. We also reached out to victims with these tools, prior to the release of this blog.
Introduction
Akamai security researchers have been researching an active cryptojacking campaign, which we believe is a resurgence of the 2021 campaign covered by Bitdefender. Although there were several correlations with the original report, this malware has leveled up since then.
One of the changes between the two campaigns is their name: The group previously known as Mexals (see their web page in Figure 1) now call themselves Diicot, and one of their tools bears the same name. Diicot is also the name of the Romanian anti-terrorism agency; in an effort to avoid confusion, we’ll refer to the threat group as Mexals. During the analysis of the modus operandi, payload chain, and IOCs, it became clear that, despite the name change, these two campaigns were related.
In this campaign we saw improved obfuscation, more inconspicuous file names, and custom mining pool proxies that weren’t present in the previous iteration. The attack chain begins with SSH credential brute forcing. Then comes a long chain of obfuscated payloads, which eventually drops an XMRig cryptominer. One of the dropped payloads is a wormable module that we think has been active in this resurgence.
We also believe that their own attack servers are hosted in a Netherlands-based VPS, and their victims are spread across the globe. We estimate the attackers have managed to mine more than US$10,000 in XMR coins.
Some hackers have a toolkit. These people seem to have a chain
We found eight executables in our analysis of the attackers’ infection chain. These executables don’t seem to differ much from what was seen by Bitdefender, except for the filenames and paths and a few new capabilities (Figure 2).
Payload name |
Usage |
---|---|
History |
A bash script. Checks if Update is running. Runs it if it isn’t. |
Update |
A compiled bash script. Notifies the attackers via a Discord webhook and runs a network scan on a random B class IP network for machines with SSH open. Supplies the results to aliases. |
Chrome/ps |
A network scanner. Accepts a class B network range (255.255.0.0) and a port. Scans the network range for machines with that port open and saves the results to a file. |
An SSH worm module written in Golang. Runs payload. |
|
The main post-breach module. Based on the resources available to the victim, it either installs a backdoor, a cryptominer, or a LAN SSH worm. |
|
.diicot |
A compiled bash script. Downloads Opera, a cryptominer. Also installs another backdoor in the form of a new user and SSH key. |
Opera |
An XMRig cryptominer. |
A compiled bash script. Is the start of the LAN spreader module. Runs an SSH port scanner on the internal LAN IP range and then calls Network to try and breach machines with SSH. |
|
Network |
Another variant of aliases with less capabilities. Performs an SSH dictionary attack on the local LAN, saves info on cracked machines (and the working credentials) to a text file. |
Fig. 2: A summary of the different payloads employed by the attackers
Binary generation and obfuscation
Luckily, we could rely on a tool built by Akamai researcher Larry Cashdollar as part of a previous SIRT alert. This allowed us to easily restore the UPX header, unpack the ELF executables, and extract the bash scripts within.
We are then left with a fully stripped, statically compiled binary, with no way of distinguishing between the malware’s code and glibc’s code (Figure 4).
We can rely on glibc’s source code to understand what the entry point looks like. The actual main function is the function loaded into rdi. Looking into it, we can find a pretty specific error string: E: neither argv[0] nor $_ works., which we can search on the web. This leads us to shc. Unfortunately, there is no decompiler easily available. Instead of reverse engineering it and creating a decryptor, which would be too much of a hassle, we can debug the payload and pause execution after a second. The decrypted shell script will reside in the malware’s memory, which we can then dump and analyze.
Infection chain
Each payload chains together relatively plainly, with various methods of setting up the next link. For example, killing competitor miners or CPU-heavy processes, cleaning bash history or installing persistence, and then downloading and executing the next payload (Figure 5).
Main payloads technical analysis
aliases
This is a Golang binary, which wasn’t stripped so we could easily find all of the malware’s logic. The malware reads two files, which were created in previous steps — protocols (user-password wordlist dropped by Update) and bios.txt (target IP list of machines with SSH open, created by Chrome). It then proceeds to do a dictionary attack on each target, and upon successful authentication, runs payload and other commands to profile the breached system.
The last command to be executed is uname -s -v -n -r -m, and its output is parsed. Specifically, it looks for specific OS names inside that output that can indicate interesting targets. For most of the OS names it looks for, it doesn’t do anything, but if the target machine is running OpenWrt, it runs another bash command on it to download and execute another shell script from 107.182.129.219, which would drop some Mirai variant. We think the focus on OpenWrt is because it’s installed on embedded devices, and could serve as an initial access vector to organizational networks. With this, the attackers show that they are interested in more than just another cryptomining campaign and are actively looking for new pastures.
After the malware finishes its breaching attempt, it reports to the attackers via a Discord webhook (an attack practice that’s gaining popularity). There are four different webhooks, with different purposes (Figure 6).
The first webhook is from a function called toDiscord, and it relegates the results of the various profiling commands run on the target machine. The next two are called from the functions toAPIlogs and toDisc, and both relegate the same information — the target’s IP and the user and password that can authenticate to it.
Finally, if the victim was running OpenWrt, another function is called toMirai, and sends the same information to yet another webhook. There is some redundancy here, which we assume is for the attackers to track different metrics more easily, or it may serve as a separation for different parts of their attack campaign (Mirai as a botnet/IAB vs. the regular use of Mirai as a cryptominer).
payload
Although it is “just” a compiled bash script, payload is interesting because it is riddled with comments and progress messages, which can teach us about the thought processes of the malware operators.
The comments and progress messages are in Romanian, which reinforces the supposition that the attackers are Romanian (the malware’s command and control/download domain literally translates to “hacker’s archive”).
The script also checks for the presence of other known cryptominers, and kills their processes — among them dhpcd and ksmdx. This shows that the attackers are aware of their ecosystem and aren’t just trying their luck in the cryptomining world.
After killing competitors and other CPU-heavy processes, the script checks how many CPU cores the machine has — if it has less than four, it just installs History and Update and a cron job for them. (The two executables are responsible for downloading the aliases payload and are scheduled to run on a reboot of the victim machine.) If there are four or more cores, the script also downloads and executes .diicot, a compiled bash script that downloads and executes an XMRig cryptominer.
Finally, if there are eight or more CPU cores, then the script downloads and executes retea, the LAN spreader.
retea
The LAN spreader module presents a new capability in the attackers’ chain. It’s another compiled shell script, which extracts all users configured on the system, and creates a file called .usrs. The file is used for an SSH dictionary attack and is populated using the extracted users and a hardcoded default password list. It then downloads and executes a network scanner on the LAN network, which detects machines with open SSH ports and writes the output to a file. Next, it downloads and executes Network, which is a lesser version of aliases, with less capabilities. Instead of installing a malicious payload or reporting to a Discord webhook, it just saves the output of the breached machines to a file, which can be later picked up by the attackers.
Meet the victims
Or are they?
Since the attackers have a wormable payload, it makes it hard to distinguish which source IP caught in our threat sensors is attacker infrastructure - and which is a victim. In this section, we'll try to dissect the attacker's infrastructure and find actual victims.
We pulled all the attacking IPs we detected (50 unique IP addresses) and geomapped them to their geographical location in the world. In addition to the attacking IPs, we also found evidence of infection at some of Akamai's customers, so they were also entered into our victim list. The geographical distribution of victims/infrastructure is shown in Figure 7.
Although most locations show very little activity, we have a few hotspots in West Europe. The spike in activity there (Figure 8) leads us to hypothesize the hotspots are actually attacker-controlled machines, while the rest are victim machines taken over by the wormable module. It seems that the wormable module isn’t particularly active, as we see very few machines active at the same time. This makes sense, since aliases is run only once per cron job execution, on a random B class. The cron is scheduled to run on machine restart, which probably happens infrequently, given the nature of the victim machines (i.e., Linux servers open to the internet).
Looking at the IP addresses that registered the most in our honeypots, which we assume are attacker infrastructure, we can see a clear distribution of hosts (Figure 9). Older IP addresses were hosted with DigitalOcean. Newer addresses (from the recent resurgence) seem to have been hosted in Serverion, a VPS and web-hosting provider from the Netherlands (their ASN is actually registered under their parent company, Des Capital B.V., a real estate agency, which confused us initially).
Attack date |
Attack count |
Attacker IP |
Hosting organization name |
---|---|---|---|
2023-02-01 |
14 |
185.225.74.231 |
Des Capital B.V. |
2022-10-01 |
72 |
45.139.105.222 |
Des Capital B.V. |
2022-10-01 |
62 |
212.193.30.11 |
Des Capital B.V. |
2022-03-01 |
22 |
195.133.40.157 |
Des Capital B.V. |
2021-12-01 |
43 |
134.209.95.47 |
DigitalOcean, LLC (DO-13) |
2021-12-01 |
37 |
134.209.195.231 |
DigitalOcean, LLC (DO-13) |
2021-12-01 |
34 |
104.248.85.104 |
DigitalOcean, LLC (DO-13) |
2021-12-01 |
27 |
134.209.198.229 |
DigitalOcean, LLC (DO-13) |
2021-12-01 |
27 |
167.71.48.128 |
DigitalOcean, LLC (DO-13) |
2021-12-01 |
74 |
188.166.60.8 |
DigitalOcean, LLC |
Fig. 9: Top attacking IPs, which we assume are attacker’s infrastructure, not just victims
Prior to the release of this blog post, we reached out to affected Akamai customers with information about the attacks, as well as to the abused emails registered for each attacking IP address.
Cash me outside, how 'bout that?
It seems that the attackers have changed their mining configuration since the previous campaign. In the past, they pointed their miners to work with supportxmr.com directly, but the miners we recently analyzed communicate with IP addresses that are probably in the attackers’ control. We were afraid those were private pools, which would mean we can’t track the payments, but our fears were unfounded — supportxmr still tracked mining payments to the wallet, so we assume their servers are just proxies to the pool hosted by supportxmr. This might be a way to evade DNS blocking and detection by not reaching out directly to the pool.
We managed to extract two different wallet addresses from the XMRig payloads we’ve seen while investigating the campaign. Those wallet addresses are different from those seen by Bitdefender, but according to their payment history, they seem to have been active during that time as well.
We can see that the payment amounts varied greatly before November 2021 (even reaching a full XMR twice), but they became much more frequent and consistent afterward (Figure 10). This could be because of a change in the payout scheme, or due to adding more miner workers — the timing corresponds to other peaks in malware activity we detected.
All in all, we estimate that the attackers have managed to mine XMR worth more than US$10,000 during their entire campaign, with more than 75% of it being mined since their resurgence. The real amount mined is probably even higher than our estimate — judging by the unique worker count reported by supportxmr, we have seen only half of the XMRig payloads and configs (Figure 11).
Summary
The payload chain employed by the threat actors is certainly impressive, and tells of a pretty sophisticated threat actor. We also usually don’t see such a long chain of payloads, and we believe there are a few reasons why the attackers chose to use so many payloads.
Obfuscation - the more moving parts in the system, the harder it is to analyze and keep track of it. The fact that the binaries are obfuscated only strengthens this hypothesis.
There are multiple people behind the threat group. Although we have no actual information on the threat actors behind the campaign, we’ve seen striking code differences among different samples of the same scripts, which we can only attribute to them having been developed by different people.
The malware campaign is built to evolve over time. We see evidence of that in the new capabilities and further obfuscation that have been added, as well in some of the redundancies in the code that were created as a groundwork for future usage.
Improvements and additions from their previous operation
UPX packing and stripping the UPX header.
Automatic update feature moved from inside the payload to outside scripts (History and Update.)
More inconspicuous file names (Chrome, Opera — mimicking browsers)
Additional malware reportings over Discord
OpenWRT specific behavior (and probably more to come)
Usage of custom mining pool proxies instead of public pools
Defender’s archive
Protecting your perimeter and network
The malware doesn’t have any novel or sophisticated technique to distribute itself. It simply uses a dictionary attack on SSH. As such, only machines that are open to SSH from the internet are at risk. Blocking SSH at the network’s perimeter, or moving it behind a VPN, can greatly reduce the risks such attacks pose.
In addition, using non default credentials or complicated passwords greatly reduces the risk of a dictionary attack like the one employed by this malware. We also recommend using SSH keys for authentication as those are even more secure than passwords (they are impossible to guess, and the “secret” is never transmitted over the connection).
Finally, we also need to consider the LAN spreader module. Since it is also using SSH for lateral movement, segmenting your network can safely mitigate that risk. If we consider servers that are open to the internet as the demilitarized zone (DMZ), then preventing SSH traffic (and generally other traffic that can be used for lateral movement, like RDP, MS-RPC, or WinRM) from the DMZ to the rest of the network is the logical thing to do. If, for some reason, you do need one of those servers to have SSH access to the internal network (because it serves as a jumpbox, for example), then moving it outside of the DMZ and under the VPN should be the preferred method. Just don’t expose servers to the internet and allow attackers to jump from them internally — reduce the blast radius and propagation paths.
Detecting infections
We’ve created a GitHub repository for tools that can assist you with detecting infections from this malicious campaign. There you'll find a bash script, a full list of IOCs and osquery queries that Akamai Guardicore Segmentation customers can use. You can also find the detection script and a partial list of IOCs at the end of this post.
In addition to those tools, we would also like to recommend a general way of detecting cryptominers that might be applied in this case — detecting outgoing traffic to mining pools by looking at the destination port. The default ports for mining pools are sometimes pretty unique, so keeping an eye out for them might prove beneficial. For example:
TCP port 4242 is the default port for this pool implementation
TCP ports 3333, 5555, 7777, 9000 are the default ports in the nodejs pool implementation
Of course, miners can also communicate with their pool over HTTP and HTTPS, in which case detection would be a lot harder. Still, it’s worth looking out for these ports.
Detection script
The detection script looks for various IoCs that can indicate past or current presence of the attack campaign. It looks for artifacts in the crontab, for their file paths as well as running processes, and also for the malicious SSH key backdoor. To run it, simply download it to the machine you wish to check, and execute it. It would scan the machine and print its verdict:
Indicators of compromise
This is a partial list of IOCs. The full list is available on our GitHub repository.
Paths
/var/tmp/.update-logs/
/var/tmp/Documents/
/var/tmp/.ladyg0g0/
/dev/shm/.x/
/dev/shm/.magic/
File names
protocols
bios.txt
Update
History
aliases
payload
retea
.usrs
IPs
107.182.129.219
45.139.105.222
185.225.74.231
212.193.30.11
Domains and URIs
arhivehaceru[.]com
discord[.]com/api/webhooks/954295081765072926/Zu7Vu-LpfgRqSmCyFvz3BCkR1Lt7clYOJeayCFzZwtPmZlVn9og_6mPS_BJY-374m5Y3
discord[.]com/api/webhooks/1036206037373571082/9bs01KrT-TrcbSAPI_i-adV1Bhn56A4X4fxzCYEw3zMq95H1mFvlKWb6-KYzvEoVfTnS
discord[.]com/api/webhooks/1036205058456563722/1_saZM0fE7nLgYG668LmDfNmSvrWpD-6Z8nIXljm0qlm6YyMxAyYuZIu4LhN2gHsgSQy
discord[.]com/api/webhooks/965651135102865479/PFdU4u8yZrn0XhzIKShcaxL3_IaBjsstYmFEXlThF2_1XCnwXSAjKos3ptwKYpPyGqvI
discord[.]com/api/webhooks/848592916951203860/WeWBGYSVreTlE0aO_6alVN3Qrj6_aRxnaDpq4_6wD04V2aHlMFvgik2Z2h78Dstg9fZY
discord[.]com/api/webhooks/1036225255049531422/qyOrT3SxHaOC-9yS2NQiPxlSMYmRFFIpU-rMKzmcDv9pQyP4uaZEiZXDXioUtf0DJLUB