Cryptominers’ Anatomy: Analyzing Cryptominers
Executive summary
This is the second installment of our three-part blog series called Cryptominers’ Anatomy. In part one, we discussed cryptocurrencies in general, their various attributes, and what makes some of them more attractive than others for threat actors.
In this part, we’ll dive into the analysis of various cryptominer samples to understand their inner cogs and gears. We will focus on cryptominers that are mining Monero and Zephyr, which are two of the coins we found to be suitable for malicious activities. In this blog post, we’ll discuss:
The use of the blockchain network to identify suspicious mining communication from a potential cryptominer malware
Four sample case studies that use different topologies to remain active and persistent for a long period
An intriguing case of a long and persistent campaign with thousands of victims that generates US$5.50 every hour
Attackers who use multiple coins in a single campaign
Detection through the network activities and cross-reference with the blockchain network
Detection through memory analysis of processes alongside consensus algorithm fingerprinting
We have also included a list of indicators of compromise (IOCs) from the case studies in this blog post to assist security teams to protect their assets.
We will wrap up this post by examining detection techniques that rely on the ASIC-resistant algorithms concepts, as well as for cryptomining operation detection. The detection focuses on the mining fundamentals and can be applied on the network level or the operation system level.
Monero network analysis
The Monero network is built using the Levin protocol to implement peer-to-peer (P2P) communication through the network nodes. It uses the protocol to distribute blockchain operations such as new transactions and new blocks. It also gives the network the ability to self-sustain in a decentralized manner through the publishing of peer nodes, and the ability to eliminate attacks through consensus algorithms.
Although we’ve used Monero as an example, network discovery of a blockchain should be possible in most of the cryptocurrencies. This is due to the distributed nature of the blockchain networks, and more details can be found in our previous blog.
Network discovery
As the Monero network is a decentralized P2P network of individual contributors, we can easily connect to it ourselves. By mapping the Monero network, we can get reliable IOCs (such as node IP addresses) and spot potential activity of the node hubs that are more connected than others.
This information can be used to detect and investigate mining operations, and it also lets us assess the network for vulnerabilities and exposure to blockchain attacks. Figure 1 is a visual representation of the Monero mining network, in which the heat map shows the density of nodes by its geographical area. We have marked nodes that are publicly open to the world with red dots.
Since the network is made of distributed peer nodes, any cryptominer must interact directly or indirectly with one of the approximately 30,000 servers in the world that can be found on our map. As we will learn, the map turned out to be very valuable for hunting cryptominer samples as well as detecting direct network connections to the blockchains. (You can find more information on our GitHub repository, including the source code for blockchain crawling and map generation.)
Cross-referencing cryptominers to the network
Using the different indicators obtained through mapping the Monero network, it is possible to identify samples that interact with the blockchain network. For example, using VirusTotal Livehunt, we can identify files containing known node addresses, which will help us detect active cryptominer campaigns (Figure 2).
Just like anything else in security, this isn’t a one-size-fits-all hunting technique. Using only this approach can lead to false positives when the server is not an exclusive blockchain node. It can also lead to a lack of visibility because the map isn’t discovering all the nodes. However, combining this technique with other indicators will increase the true positive detection rate.
The map contains publicly accessible nodes alongside recently accessible nodes. Some of the nodes are used for more than a Monero node; for example, serving as a mirror of Python’s PyPi repository or any other service. Figure 3 is an example of a server that provides multiple services, which can cause a lot of distraction in the hunting process. We eliminated these servers from the analysis to reduce potential false positives.
Qualifying out irrelevant samples is just as important in threat hunting as qualifying in relevant samples. Network analysis combined with a cross-referencing approach can unveil cryptominers and entire mining campaigns orchestrated through botnets. By incorporating additional static analysis techniques, such as matching hardcoded wallet addresses, we can efficiently focus on the most relevant malicious samples.
Analyzing cryptominer samples
Because of the noisy nature of cryptomining, it can be easy to detect their operation even with a “naked eye.” An alerted IT professional can detect the anomalies generated by cryptominers without requiring any sophisticated anti-malware tools. Even nontechnical people are aware of their machine’s baseline performance, and if it gets sluggish, they will likely get it analyzed by a professional who would easily find the root cause. Because of this, many cryptominers do not bother to protect the malware against analysis and detection but instead act through the strategy of untargeted mass infection.
In the following case studies, we will cover some of the cryptominer samples we identified in the wild and examine some of the most interesting details about their operation and behavior. Two main factors were used to find these case studies: (1) a relevant coin as described in the first blog post in this series, and (2) the mining topology they exploit.
Case study #1: A persistent and massive campaign
As part of this research, we analyzed a variety of cryptominer samples — one of them was a 6-year campaign. As is typical with long-running campaigns, it seems to be either an organized operation or a malware distribution service that deploys the cryptominer for a third party.
Analysis of that sample shows it has multiple proxies that accumulate to a hashrate of 5.6 Mh/s, which equates to thousands of compromised machines (Figure 4). This is a massive and persistent attack, and since the hashrate remains steady, the malware probably remains undetected by most of its victims and continues to run unimpeded. That kind of attack is an extremely lucrative campaign for an attacker.
The campaign has been active at least since June 2018, and contains indicators (e.g., language used in the samples) that could possibly point to a collaborative effort between Russian and Chinese threat actors. Analyzing the command and control (C2) servers also supported this theory, but as of the publication date of this post that has not been fully confirmed.
At the time of writing, the attacker has accumulated at least 1,702 XMR, valued at approximately US$280,000 at today’s exchange rate. Spread over six years, this amounts to an average of nearly US$47,000 per year from one single campaign.
Most of the samples linked to this campaign use a scripting language corresponding with the operating system of the victim as the initial loader and downloader. It relies heavily on routing and misleading network connections, likely in an attempt to decouple the malicious file from the C2 server.
After analysis of the campaign samples, we identified that it uses PowerShell to deploy an executable called loader in a stealthy way using the r77 rootkit. Even without analyzing the complex dropper, we can see there are multiple versions of this cryptominer.
In some versions, the cryptominer itself contains the config.json file, which holds the mining configuration. In other samples, the OracleLoader script drops the cryptominer, and sets up the configuration. The malware also has an updating mechanism that could recover the botnet in case of a compromise (Table 1).
Characteristic |
Value |
Note |
---|---|---|
Malware name |
Oracle Loader |
|
Current version |
1.1.72.0 |
<5.133.65.53>/Oracle/ver$77_loader.exe.txt |
Related components |
|
Table 1: Oracle Loader characteristics
The malware also listens on port 999, exposing the HTTP API feature of XMRig. This lets the attacker access the victim’s miner and helps them monitor the mining process. If the victim machine is directly connected to the internet and is not behind a network address translation (NAT) router or an external firewall, we theoretically could find the victims through network monitoring services like Shodan. Figure 5 shows the result of a Shodan query used to detect potential victims.
Using the XMRig worker monitor web app to monitor the victims’ miners, we can reveal information about them such as CPU model and hashrate. This interface only enables us to query information, so although we can see activity, we can’t control the miner through it nor shut it down (Figure 6).
As we can see in the mining pool dashboard, the steady hashrate suggests the victims are all over the world, otherwise we would expect an alternating hashrate based on the time zone active hours. Another explanation might be that the attacker is targeting servers and not consumers as other cryptominers campaigns do.
Case study #2: Public pool topology used by a Zephyr cryptominer
Although there are some highly motivated and sophisticated attackers with long-term campaigns that rake in huge profits, like case study #1, they do not make up the majority of the threat. Cryptominers that use public pools are the most common. These cryptominers do not contain sophisticated features such as obfuscation or anti-analysis techniques. A typical modus operandi would be to contact the pool directly with a plaintext wallet address. They also usually have smaller impact and profit.
The cryptocurrency market provides several options for attackers to choose from, with varying mining profitability and coin value. Despite the inherent financial aspect of cryptomining, the mining profitability of a currency is apparently not the most important consideration for many attackers. The Zephyr coin, which is less profitable than Monero, is very common among threat actors. The volatility of the crypto market is a consideration for attackers and legitimate crypto buyers alike. It could be the potential long-term value that attracts them to one cryptocurrency over another.
The largest Zephyr campaign we’ve seen has more than 1,400 active victims with a total hashrate of 800 Kh/s and total profit of 906.3 ZEPH, which is currently equal to US$2,528.
We can determine when an attacker targets specific regions geographically by inspecting the hashrate of the botnet over time. An example of this lies in another observed campaign that uses proxies combined with direct connection malware that seems to be targeting Russian-speaking users (Figure 7).
The periodic changes can indicate that most victims are human users and not servers, as personal machines are more likely to be turned off periodically. If we analyze the frequency of the hashrate, we can see that the cycle is 24 hours long, and under the assumption that the low point is nighttime, it’s possible to locate the time zone in which most of the victims live (Figure 8).
The time intervals alone are not enough evidence of victim location, but our theory was supported by the IP geolocation lookup feature provided by the Hashvault pool. By combining this with malware analysis and the malware delivery names that are games-related, such as Fortnite, Solara executor for Roblox, and others, we can come to a more solid assumption — the malware is pretending to be a cheat engine tempting players to find it. We also suspect it spread through social media and messaging applications, such as Telegram and Discord.
Case study #3: Cryptominer using a mining proxy topology
We used the Monero network map to gather information on more than 25,000 nodes, but only 10% of them were directly reachable. Inversely, we also used this map to filter out any known cryptominer that is not contacting the network, which is how we found a campaign that has been active since April 2022.
Figure 9 shows the malware’s attack vectors: It uses a mining proxy like XMRig-proxy and distributes its cryptominer through pirated software, like cracked Internet Download Manager (IDM).
The attack flow is similar among the campaign malware samples. It usually starts with a drive-by download from crackingcity.com, which sets off a payload chain. Then, in the last stage, it deploys the cryptominer dlIhost.exe that connects to a proxy hosted in custompool.xyz. The attacker uses environment variables to pass strings as arguments to its child process, mainly batch files, as an evasion technique. It works by decrypting embedded archives and executing scripts or files after manipulating the defender exclusion list.
The attacker registered the proxy domain under the name custompool.xyz on April 29, 2022, a mere three days after the first detection on VirusTotal. The first sample, called VScan.exe, is a self-extracted archive that uses two batch files. The first is main.bat, which uses a hidden password in the environment variables to extract the second-stage batch file VS.bat. We can extract the hidden information using a debugger in two ways: break when an environment variable named "l3" is accessed (Figure 10) or break on every modification of the environment variables.
Using the password un#912345678@rar, we can extract the second-stage loader that connects to the other C2 domain, crackingcity.com. In the final stage, the malware executes dlIhost.exe (essentially a modified XMRig client with embedded configuration to the custompool.xyz pool), which at this point is the direct IP (Figure 11).
Now there is a question about the type of server. Is it a private pool? A mining proxy? Or is it some sort of custom node that we consider the same as a private pool? To answer these questions, we need a way to extract some identifiers from the server. Solo mining through a dedicated node requires the miner to operate in daemon mode (where the RPC request is transmitted over HTTP), which is not present in this configuration, so this clearly is not the case.
JSON structure is preserved across serialization, which allows us to try to get responses from the server by sending the various stratum methods that XMRig-proxy supports. If the responses from the server match the order of keys and values, this could be a strong indication the server uses XMRig-proxy or is based on it.
The XMRig supports three Stratum protocol methods:
- Login — the first request initiated by the mining worker, which usually contains the wallet as the login
- Keepalived — just keep the connection alive
- Submit — submit the result when a valid share is found
When an invalid method is requested, the XMRig-proxy will answer with an error (Figure 12). This can be indicative of the server type because other services, like pools, just ignore the bad request rather than error out. Combining all this brings us to the conclusion we are dealing with XMRig-proxy.
We have split the submit method into three cases that should return explicit errors from an XMRig proxy (Table 2).
A low-difficulty share is when the miner submits a hash with a value lower than the expected target.
An invalid nonce is a result of out-of-range nonce according to the nicehash design.
A maximum difficulty hash is the specially crafted hash that will probably satisfy any job’s target. With this case, we are bypassing the XMRig proxy difficulty validation and transmitting directly to the pool, which returns the pool error.
Request |
XMRig-proxy |
MoneroOcean |
HashVault |
Nanopool |
SupportXMR |
C3Pool |
Login |
(baseline) |
✕ |
✕ |
✕ |
✕ |
✕ |
Keepalived |
(baseline) |
≈ |
✅ |
≈ |
✕ |
≈ |
Unknown |
(baseline) |
✕ |
✕ |
✕ |
✕ |
✕ |
Submit — low difficulty |
(baseline) |
✕ |
✕ |
✕ |
✕ |
✕ |
Submit — invalid nonce |
(baseline) |
NA — blocked IP |
✕ |
✕ |
✕ |
✕ |
Submit — maximum difficulty |
Repeat pool response message |
NA — blocked IP |
✅ |
✕ |
✅ |
✅ |
Table 2: Comparison of the Stratum protocol requests across XMRig-proxy and various public pools; ✅ denotes same as baseline, ✕ denotes different data, and ≈ denotes same data different order
Not only can we distinguish XMRig-proxy from commonly used pools, but we can also distinguish among the pools themselves. This information could be handy when we route to a pool through other network components, such as reverse proxy. In this case, when we submit mining results with the maximum difficulty we get the error from the back-end pool rather than the proxy. By using this information we can identify that the attacker uses Nanopool, but since we don’t have the wallet address we can’t get an assessment of the victim count for this campaign or its profit.
Case study #4: Concealed blockchain communication using a Stratum proxy topology
Stratum protocol proxy operates at the network level by forwarding Stratum protocol requests directly to another server without modifying the wallet addresses. This ensures that each miner's work is credited to their respective wallet. Implementation of a Stratum proxy can be achieved using a basic transport layer network proxy or a specialized application proxy that understands and handles the protocol.
We found an active campaign that uses this topology and connects to a public pool through a stratum proxy. We couldn't identify whether it’s a reverse proxy on the network level or whether it intercepts the Stratum protocol itself and operates as an application proxy. Either way, it redirects the Stratum messages to hide the back-end pool or node. Scanning public pools for the provided wallet reveals it contacts the MoneroOcean public pool.
The campaign has been active for at least four months and its total profit is 1.158 XMR (roughly US$180). On its own, it’s not a very successful campaign, but the apparent effort of the threat actor points to potential larger plans that include developing the whole campaign themselves — the infrastructure, the cryptominer, and the different malicious files to drop it. The attackers also distribute the campaign themselves without relying on third parties, while implementing anti-reverse engineering mechanisms, including encryption, obfuscation, and the prevention of the use of monitoring tools (Figure 13).
Although the campaign may be lazy, we can see a thoughtful execution of the malware, notably in the obfuscation process. The malware tries to hide the payload by downloading an archive during runtime and executing processes with legitimate system files names.
Detections
There are several different avenues you can take when it comes to detections in general. Each method may not stand on its own, but it will if it’s used in conjunction with other detection mechanisms. Cryptominers are not an exception; in fact, they can be difficult pieces of malware to detect because of their benign characteristics. They use the only thing that does not require a special permission in most operating systems — computation (CPU time).
Connections to the network
To detect these miners, we can cross-reference the blockchain network (like the Monero network that we scraped earlier) with the data we get from a network visibility tool, like a firewall or segmentation solution. Since every node or pool has to interact with the Monero blockchain, this provides network administrators with invaluable insight on the traffic that is coming out of their network. When coupled with network ports, it makes detection much easier, since most cryptominers use distinct port numbers, such as 999, 3333, or 7777. Although Monero is used in this case study, the blockchain network mapping can be used in all Proof-of-Work (PoW)–based networks.
It is important to note, however, that not all traffic to Monero nodes is necessarily cryptomining, as those nodes sometimes provide more than one service. For instance, IP 157[.]90[.]212[.]53 is found in our Monero network map, but it is also an exit node for the Tor network. There could be many explanations for why a Monero node provides other services; it may be compromised or simply intentionally multipurposeful. Either way, using the connection to the network without additional information may be a weak indication of connection to the blockchain and generate false positives. This is another reason why port number information is crucial for accurate detections.
Another reason for false positives can be a low update rate of the map. A legitimate server can be assigned with an IP address that was previously used by a Monero node and cause a false positive if the map is not up to date.
This detection can’t stand on its own but could be used as a trigger for a more comprehensive detection logic or investigation. Any operation of cryptominer must include communication with a stratum server for a mining job assignment. Usually, it operates with publicly known mining pools, but in some cases, it can be hidden using a proxy, which won’t appear on the network map.
Algorithm execution detection
Cryptominers intensively use the victim’s computing resources, so monitoring the system for usage spikes could indicate an infection. But just like with the network map cross-reference, it doesn't stand on its own as an accurate detection.
Combining multiple detectable IOCs will increase the detection confidence rate; in other words, it reduces false positives. For a mining operation to be successful, there are essential counterparts. Cryptominers must mine the chosen coin using its consensus algorithm as proof of work. Every algorithm like this has a unique fingerprint in the system during runtime, and extracting those features can create a solid method of detecting malicious cryptominers.
ASIC-resistant algorithms, such as RandomX, usually implement a complex set of operations that can be uniquely identified. For example, the developer of RandomX created a detection tool based on this exact assumption. By iterating the running threads in the system, we can probe the thread state, including the CPU registers’ values. Since RandomX is implemented using many of the modern features of CPUs, using the Rounding Control configurations as in the detection tool by the developer of RandomX is one way to do it.
In fact, combining it with other indicators, such as hardware AES operations and hugepage configuration, will improve the detection rate. In summary, detection can be achieved by looking for unique AES keys in the SSE registers or by querying the thread access token privileges, respectively.
We can extend these methods to other operating systems, as well, because most of the cryptominers aim to be platform-agnostic and should behave the same way even on different operating systems. Not being pigeonholed into one operating system allows a campaign to be potentially more successful as the target numbers drastically increase this way.
Locating the wallet in process memory
When cryptominers communicate directly with the mining pool rather than through a proxy, the miner’s wallet should reside in the process’s memory. This is because the Stratum protocol requires the miner to authenticate the server and let it know what account should be rewarded on valid share submissions. Typically, it will use a wallet address, and for Monero mining, specifically, the miner will probably be based on the XMRig software. Using these assumptions, we can find and intercept the wallet when it is sent to the pool by hooking into the various socket APIs, or (theoretically) we can use a machine-in-the-middle (MITM) “attack” to intercept the authentication message sent by the miner.
We can also use a simple Regex search over the entire allocated memory of the process to find the 95-character wallet address as it follows a strict format. It starts with 4 or 8 and consists of BASE58 valid characters. So, the pattern /[48][1-9A-HJ-NP-Za-km-z]{94}/ could be sufficient for this task, and can be embedded in a YARA rule, as well. The scanning can be conducted any time after the first connection of the cryptominer to the pool, because the miner must keep the wallet address available in case it needs to reconnect.
Finally, we can use any of the techniques mentioned to find other strings related to the Stratum protocol and parsing the wallet from within. Such indicators could decrease false positives since the protocol’s JSON structure is much more unique. For example, see the login request in Figure 14; we can create a stronger signature that contains multiple keys for a more accurate detection.
{
"id": 1,
"jsonrpc": "2.0",
"method": "login",
"params": {
"login": "<wallet address>",
"pass": "<Usually the worker name>",
"agent": "<Usually xmrig agent>",
"algo": [
"rx/0"
]
}
}
Fig. 14: An example login request; matching the pattern could provide more accurate detection
Conclusions
Akamai researchers will continue to expose malicious campaigns and the threat actors behind them, as well as identify IOCs to aid in the protection of both our customers and the general public.
In this second part of our three-part cryptominer blog series, we have demonstrated a number of techniques to reveal more information about various campaigns, including identifying a mining pool behind a mining proxy or locating the campaign’s geographical operation by analyzing the hashrate of the cryptominer botnet over time, and more.
We saw malicious cryptominers that used Zephyr alongside the well-known Monero. By using the different mining topologies, the cryptominers were able to hide information and minimize the number of identifications and compromising indicators.
After realizing the anatomy of the different cryptominers and the mining process, in general, a question was raised: Can we stop the mining operation of the cryptominer botnet? Stopping the mining operation effectively would shut down the cryptominers that infect victims' machines and consume their resources. We will explore this question in the final installment of our series.
To keep up with this series and other breaking security research, you can check out our security research page and follow us on social media.