Executive Summary
Aeternum is a recently discovered C++ botnet loader that shifts its command-and-control (C2) infrastructure entirely to the public Polygon blockchain. Instead of relying on centralized servers or domains, threat actors operate Aeternum by writing encrypted and plaintext instructions directly using smart contracts. A smart contract is a self-executing program stored on a blockchain that automatically runs when specific conditions are met.
Infected devices continuously query public remote procedure call (RPC) endpoints to retrieve and execute these on-chain commands.
The Aeternum botnet uses decentralized networks and evasion techniques, such as virtual machine detection and antivirus scanning, to operate effectively. This combination establishes a highly resilient, low-cost threat that complicates existing law enforcement takedown methods.
In this article, we analyze three malware cases linked to the Aeternum botnet:
- Aeternum’s loader, C2 and downloader communications
- Related Python-based malware using the Telegram API for C2
- A blended threat consisting of XWorm RAT, the XMRig cryptocurrency miner and data exfiltration
Palo Alto Networks customers are better protected from the threats discussed in this article through the following products and services:
- Advanced WildFire
- Advanced URL Filtering and Advanced DNS Security
- Next-Generation Firewall with Advanced Threat Prevention
- Cortex XDR and XSIAM
If you think you might have been compromised or have an urgent matter, contact the Unit 42 Incident Response team.
| Related Unit 42 Topics | Malware, Blockchain, C2 |
Background on Aeternum
This article builds upon research by the Ctrl-Alt-Intel team on the Aeternum C2 architecture and the loader binary. That previous research primarily focused on host-based activity.
This malware advertises itself as Aeternum C2 BotNet Loader, and security researchers call it either Aeternum C2 or Aeternum loader.
Our analysis focuses on three malware samples associated with Aeternum activity. Our first sample is the Aeternum loader.
Sample One: Aeternum Loader
SHA256 hash: 5bfb25b8255b61e5ffdf6804451534bcfa9f1dfd225e6c8cdcefb5f50d846898
Sample Characteristics
This Aeternum loader sample is named Build.exe. It is the initial UPX-packed 32-bit portable executable (PE) Windows malware file compiled in C++. Its primary functions are to establish a persistent presence, perform reconnaissance and communicate with the decentralized Polygon blockchain to retrieve encrypted C2 commands.
Behavioral Analysis
The overall flow of this sample executes in multiple stages:
- Initial execution and self-unpacking
- Build.exe executes a multi-stage self-unpacking sequence
- Persistence and setup
- Creates a folder under the user's AppData\Local directory and copies itself to it
- Creates a Windows shortcut under the program menu's Startup directory (Wmi_Framework_APIKEY_wmsnet_<random_value>.lnk) to ensure auto-launch upon reboot
- Executes supporting binaries (wmiframework.exe, ZrvEsJQzWQ.exe, STAAAAAS.exe)
- Configuration retrieval and network communications
- Deobfuscates global configuration data to produce parameters used to construct network endpoint strings
- Sends JSON-RPC requests to Polygon RPC endpoints (decentralized C2 communication)
- Queries immutable smart contract addresses using the contract method 0xb68d1809 to retrieve encrypted C2 commands
- Decrypts the payload using a weak PBKDF2HMAC/AES-GCM routine
- Downloader and payload execution
- Downloads files as instructed by the C2 server, such as a clean putty.exe and the malicious DotNetZip.dll, from GitHub repositories
- Executes the malicious DLL, which uses hard-coded credentials to connect to a Telegram C2 bot (DLLSendC2Bot)
- Exfiltration
- Packages the stolen information for exfiltration over encrypted channels to trusted domains, code-hosting platforms and the Telegram API
Static Deobfuscation (XOR)
The pattern of encryption keys for the Aeternum loader (i.e., \x00\x00\x00[ENC bytes]\x00[KEY bytes]\x00\x00\x00) consists of:
- Three null bytes followed by the encrypted payload bytes
- A null byte, followed by the key bytes
- Three null bytes
Since the pattern is known, a script can identify the different number of occurrences along with its offsets. When found, we can then use the key to deobfuscate the hidden information.
Figure 1 shows two examples of the decryption process against two different obfuscated string matches and their deobfuscated values. These values consist of the JSON object strings used for HTTP-based C2 communication during the execution of the malware and its subsequent interaction with the Polygon blockchain.
Additional deobfuscated strings also include:
- Polygon RPC endpoints (i.e., hxxps[:]//polygon-mumbai-bor-rpc.publicnode[.]com)
- File extensions (.e.g, .ps1, .dll, .exe)
- HTTP header information (i.e., User-Agent)
- C2 command information (e.g., hwid, args, ping)
- Smart contract method (i.e., 0xb68d1809)
However, we suspect that this particular sample differs from others, since we did not find the smart contract addresses either through deobfuscation or plain-text pattern search. During network analysis, this sample used 22 different smart contract addresses during C2 communications.
The full table of deobfuscated strings can be found in the Indicators of Compromise section of this article.
Network Traffic
The Aeternum loader performed the following activities as part of its downloading and C2 communications:
- Communicating with the Polygon blockchain network
- Downloading files from GitHub repositories
- Interacting with social media via Telegram’s API (api.telegram[.]org)
Figure 2 shows an example of the communications traffic filtered in Wireshark.
Aeternum Polygon Blockchain C2 Communications
This section explores how Aeternum performed C2 communications on the Polygon blockchain and how it uses different smart contract addresses to retrieve C2 commands.
Polygon’s JSON-RPC (HTTP Request Analysis)
This sample made a JSON-RPC request using HTTP to the Polygon blockchain. Figure 3 shows the TCP stream of an HTTP POST request to the Polygon RPC endpoint, which includes a JSON object with two important fields: to and data. The to field contains the contract address, and the data field contains the Polygon contract's getDomain() method 0xb68d1809.
| Type | Value | Description |
| SHA256 hash | 5bfb25b8255b61e5ffdf6804451534bcfa9f1dfd225e6c8cdcefb5f50d846898 | Aeternum C++ loader executable |
| SHA256 hash | 1505eda3da68e2ff9919b55a31018bd30a991236f041aee835f3bc4e430ce505 | Malicious downloaded DotNetZip.dll |
| Filename | DotNetZip.dll | Malicious payload executed by the loader |
| Filename | putty.exe | Benign file downloaded for testing/staging |
| Filename | Wmi_Framework_APIKEY_wmsnet_<random_value>.lnk | Startup link for persistence |
| Filename | wmiframework.exe, ZrvEsJQzWQ.exe, STAAAAAS.exe | Supporting binaries |
| Domain | api.telegram[.]org | Telegram API endpoint for exfiltration/C2 (used in DLL). (This domain is not inherently malicious, but could be viewed as part of a potential pattern of suspicious activity.) |
| Repository | hxxps[:]//github[.]com/lencod/ | Repository hosting malicious file artifacts |
| Repository | hxxps[:]//github[.]com/Mash3Do/ | Repository hosting malicious file artifacts |
| Telegram ID | -4991861036 | Hard-coded chat-id for Telegram C2 bot |
| Telegram Token | 8305917772:AAHAou... | Hard-coded Telegram bot API token |
| Contract Address | 0x04E25a563f159308FC3E15fE9Ccc9D2CF623D0cc | Sample 1 Polygon smart contract address |
| Contract Address | 0x16dA95799CB8aB203f83e01AFC030B1217198Da4 | Sample 1 Polygon smart contract address |
| Contract Address | 0x1D50703722729dD68e89D819F69eFc5Fb206bBe7 | Sample 1 Polygon smart contract address |
| Contract Address | 0x27c7c36981c1ed5cFA2DCDb4B43C27A6BaF6bEa8 | Sample 1 Polygon smart contract address |
| Contract Address | 0x4dcE7d4b1229F3705BDB70341484cF2EEE36432e | Sample 1 Polygon smart contract address |
| Contract Address | 0x55b4F951d5Ac035C21B170C73C0A930a641b718C | Sample 1 Polygon smart contract address |
| Contract Address | 0x6da31EB2A016074ffd5519326573E78E2677E4C8 | Sample 1 Polygon smart contract address |
| Contract Address | 0x737791081A398151195a753Fb49f9c1b8bc1fCDB | Sample 1 Polygon smart contract address |
| Contract Address | 0x7D2D8A4A6E8D89cf5C151C4f68A521490D9779B0 | Sample 1 Polygon smart contract address |
| Contract Address | 0x8d2BaEc2687F59eE1EE7BFd322D33325f5E004ee | Sample 1 Polygon smart contract address |
| Contract Address | 0xb3EF2D08Bf25a7daB9d8b98d64E564eA1f6Db924 | Sample 1 Polygon smart contract address |
| Contract Address | 0xb8fB2bfb182A172b29C365AD6CF743449975C418 | Sample 1 Polygon smart contract address |
| Contract Address | 0xbD6e817Cc510EC3DA5651B5a3AC595d34C0CF1af | Sample 1 Polygon smart contract address |
| Contract Address | 0xC37fB924cF5996C9e676BBA399bDfc5F936B3572 | Sample 1 Polygon smart contract address |
| Contract Address | 0xC41342908f98E813862EDFe47Ac3af676F8098C9 | Sample 1 Polygon smart contract address |
| Contract Address | 0xc7199C1dbCd82c4E002327Aa3EC9158F434a6aCE | Sample 1 Polygon smart contract address |
| Contract Address | 0xCE476E6f4d83a7a086Cbcdf0FE2E8f221e47e81C | Sample 1 Polygon smart contract address |
| Contract Address | 0xD69A36439FffD145ADAcacB94fDe6f8b3546a361 | Sample 1 Polygon smart contract address |
| Contract Address | 0xf9438b4E3200AE1611eD3d03310c803FDdf67672 | Sample 1 Polygon smart contract address |
| Contract Address | 0xfbC267200f9e5749045f32dbB55BB16615f1CE5F | Sample 1 Polygon smart contract address |
| Contract Address | 0xFDB8b139EeacD17ea7c10c256eA77Ba6Dff18D7d | Sample 1 Polygon smart contract address |
| Contract Address | 0xFdfB8c4e827c2d053749C8F2f2058548dde0d073 | Sample 1 Polygon smart contract address |
| RPC Endpoint | hxxps[:]//polygon.rpc.hypersync[.]xyz/ | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//polygon-mumbai.g.alchemy[.]com/v2/demo | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//polygon-mumbai-bor-rpc.publicnode[.]com | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//api.noderpc[.]xyz/rpc-polygon-pos/public | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//polygon-mumbai[.]gateway.tenderly[.]co | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//public.stackup[.]sh/api/v1/node/polygon-mainnet | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//gateway.tenderly[.]co/public/polygon | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//polygon-amoy.gateway.tenderly[.]co | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//rpc[.]poolz[.]finance/polygon | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//gateway.tenderly[.]co/public/polygon-mumbai | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//api.zan[.]top/polygon-amoy | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//endpoints.omniatech[.]io/v1/polygon-zkevm/testnet/public | Polygon RPC endpoint |
| RPC Endpoint | hxxps://rpc[.]polygon-zkevm[.]gateway[.]fm | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//polygon-pokt.nodies[.]app/ | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//polygon-amoy.therpc[.]io | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//rpc.polygonsupernet.public.arianee[.]net | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//public.stackup[.]sh/api/v1/node/polygon-mumbai | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//polygon-zkevm-mainnet[.]public.blastapi[.]io | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//polygontestapi.terminet[.]io/rpc | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//polygon-mainnet.g.alchemy[.]com/v2/demo | Polygon RPC endpoint |
| RPC Endpoint | hxxps[:]//polygon-zkevm.drpc[.]org | Polygon RPC endpoint |
| Type | Value | Description |
| SHA256 hash | f2a326cff405299e4ebdfaac955c52fc7e496544eaa0921ecad4816cb3ae3a27 | XBinderOutput_protected.exe (Main sample) |
| SHA256 hash | 4e24bbd0fabac6c3efcec943046afbfd332b2c0108a13becfda23a0e26f9ff5f | XWormClient.exe executable |
| SHA256 hash | 81bb80d9c5a97dc41b65f6248c131963c91346eb4fb672836b3d53ae67564d9f | XMRig coin miner (miner.exe) |
| Domain | gulf.moneroocean[.]stream | XMRig mining pool |
| Wallet Address | 82pNS8tBnvZ5cmV1iU9cXdQmhGz95P18fZpASBrxtaSF1ToTmZtf3HGHrdXMt1Znuu8BLU17koPs2hTXxTajdTviLcgbbAi | XMRig Monero wallet |
| IP Address:Port | 193.221.200[.]219 | HTTP C2 exfiltration IP address |
| C2 URL | hxxp[:]//sekirolegion.duckdns[.]org/api/endpoint.php | C2 contacted by malware (linked to exfiltration IP) |
| Contract Address | 0x75cD25791A60ab3451E2d2feB5ec46c6f541C2B8 | Sample 2 Polygon smart contract address |
| Type | Value | Description |
| SHA256 hash | ea1b6ff3a0c1a749b9f09d66789973321d63d8896b48f7345193bdad512950a2 | Python script sample |
| Staging Domain | download.sftp-api-group-wechat[.]com | Staging domain for malware components |
| C2 Domain | update.constant-path[.]xyz | C2 domain (retrieved from contract) |
| C2 Domain | update-launcher[.]xyz | C2 domain (retrieved from contract) |
| C2 Domain | test-steve[.]cyou | C2 domain (retrieved from contract) |
| Telegram Bot | 7356125890:AAF5ncBIc2pJrEfYPAmy2g9YS7B5NjmtwTc | Telegram bot token for exfiltration/C2 |
| Telegram Chats | -1002535992165, -1002144122983 | Telegram chat IDs |
| Contract Address | 0xb0874252a7359AA701F3F144A1f03A6e0DA8aE6D | Sample 3 Polygon Smart Contract address |
| XOR Key | helo1 | XOR key for C2 |
| XOR Key | $m7*rYpry3 | XOR key for domain decryption |
| Persistence | PythonLauncher-*.lnk | Shortcut created in Windows Startup folder |
| Injected Process | dpapimig.exe | Signed binary used for Early Bird APC injection |
| Disguised Binary | WmiPrvSE.exe | Disguised binary |
| Type | Value | Description |
| Function Selector | 0xb68d1809 | getDomain() function selector (used by all samples) |
| Function Selector | 0xb249cd2d | updateDomain() function selector (admin only) |
| Function Selector | 0xf851a440 | admin() function selector (auto-getter) |
| Operator Address | 0xcaf2c54e400437da717cf215181b170f65187abf | LenAI's primary smart contract address |
| C2 Domain | hxxps[:]//cdnjsdelivr[.]beer/ | New C2 domain pushed by LenAI via updateDomain transaction |