A Miner Was Only the First Clue: From Docker to Hermes and AdaptixC2
154[.]201[.]66[.]125- ASN
- AS401696
- Provider
- cognetcloud INC
- Netblock
- 154[.]201[.]66[.]0/24
- Location
- IPinfo and RDAP: Hong Kong; event MaxMind: Seychelles
A miner was only the first clue
The case began with Docker requests that looked like routine cryptomining. All four sources submitted container-create requests between the 21st and 28th of September 2026; 154[.]201[.]66[.]125 also submitted the recorded exec requests. A Monero wallet or miner-script URL linked each source. Two sources submitted host-prefixed credential searches; 154[.]201[.]66[.]125 supplied the SSH public key.
The payload URL identified a TCP/8899 server whose root exposed miner installers, exchange and wallet harvesters, a 900-worker scanner targeting TCP/9119, and an archive named hermes-internal.tgz.
Git and repository links
The archive retained a shallow Git clone whose origin pointed to hxxps://gitea[.]com/blanket/sink. Its plugin files were byte-identical to that public repository. The same account also hosted master, containing x86-64 and ARM64 AdaptixC2 Gopher agents. Its argument repository contains arg.sh, configured to pull targets from hxxp://144[.]31[.]51[.]6:8080/targets, match Hermes dashboard responses on TCP/9119, and upload matching results to a configured ProjectDiscovery Cloud account under asset name hermes.

The open-directory wide_scan.py independently scans only TCP/9119, linking the staging directory to the same Hermes discovery pipeline.
Hermes plugin and Gopher agent
The first artifact is a Hermes dashboard plugin. It registers a hidden /internal tab labelled Hemes Internal. Inside the dashboard's existing authenticated and allow-listed plugin context, its API passes commands to subprocess.run(..., shell=True) with a 30-second timeout and returns their output. A second endpoint profiles GPUs through nvidia-smi, falling back to lspci.
The second artifact is AdaptixC2 Gopher. The companion installer selects an architecture and defines commands to write the agent to /usr/local/bin/hermes-internal and enable hermes-internal.service as root. Each binary holds one authenticated AES-128-GCM profile. Both decrypt to the default Gopher watermark 0x904E5493, raw TCP without TLS, and the configured Gopher address 144[.]31[.]51[.]6:4475. The address is a static artifact value.
The retained Gopher builds provide shell, PTY, file, and process operations and TCP or SOCKS tunnelling. Their BOF handler returns Need Windows! on Linux.
Credential harvesters and miner installers
exk.py extracts credentials for 10 exchanges and signs balance requests for OKX, Bybit, Binance, and Gate using candidate keys. Other scripts search for environment files, mnemonics, Ethereum-style hexadecimal private keys, and Solana-style Base58 values. They write results to local dotfiles that defenders can preserve during scoping.
The miner installers evolved through kinst7.sh and kinst8.sh, which stage files under $HOME/.cache/uv. They write XMRig configuration, maintain watchdog loops, and attempt to display the process as kworker/u2:1.
Defensive priorities
Remove unauthenticated Docker TCP/2375 exposure and review external container-create and exec requests. Hunt both hermes-internal placements: Hermes plugin directories and /usr/local/bin/hermes-internal with its systemd unit. Search for .kwdb, .kw.json, /etc/cron.d/.sysmon, credential-harvester output files, and userland processes displayed as kernel workers. Revoke exposed exchange API keys. Move assets from exposed wallet keys or seed phrases to a newly generated wallet using a clean system. Use the Full Report's network, YARA, and host detections and typed indicators.
- crypto_address0x139a8591a5c79642b947f5f2527294cfaa0044ecPolygon beneficiary in the separate blanket/myst repository
- crypto_address84EavBZ5AxEa9d6TriCcHp25U3243fL2RB9ZSy2z9GfMiDFARrvvbEsHZzhzsr6HRvfvKUNHS9ph8AvqXDy3CFTR2KaxaR5Monero wallet shared by the four-source Docker activity and installer family
- domainexxai[.]youling[.]xyzcertificate-backed name resolving to the staging host
- domainvps2391102[.]fastwebserver[.]dePTR of 217[.]79[.]178[.]122 and exact /cmd/ filename anchor
- filename.exk2.outexk2.py result file
- filename.exk.outexk.py result file
- filename.fsweep.outfsweep.sh result file
- filename.wk.outwk.sh result file
- file_path$HOME/.cache/uv/.kwdbkinst7.sh watchdog
- file_path$HOME/.cache/uv/.kw.jsonkinst7.sh XMRig configuration
- file_path/etc/cron.d/.sysmoncron path requested through a host-prefixed Docker path
- file_path/etc/systemd/system/hermes-internal.serviceGopher persistence unit
- file_path/usr/local/bin/hermes-internalGopher installer destination
- ip138[.]124[.]36[.]211Docker request source on the 21st of September 2026; shared Monero wallet
- ip144[.]31[.]51[.]6static Gopher configuration on TCP/4475 and HTTPX target source on TCP/8080
- ip150[.]241[.]65[.]101Docker request source that requested cron delivery of kinst8.sh
- ip154[.]201[.]66[.]125Docker request source, staging host, and payload mirror
- ip158[.]178[.]239[.]182third payload mirror referenced in 12 installer scripts
- ip217[.]79[.]178[.]122Docker request source on the 26th of September and payload mirror in installer scripts
- sha2562b86bfd7d52260b281001b4aebc2bbb0b125180f9af21dcbe0c5a9cc7085806dretained exk2.py exchange credential harvester
- sha2562e434f3ba0f00abb01b71635712c3f1fa21865bac24cc7312d5c56eafb005dabretained exk.py exchange credential harvester
- sha25654cdd3ee0b3ab90720a0de7cadff5b969ceada77dd901e5698a3c5bae3c6c241retained wide_scan.py port 9119 scanner
- sha256587df9e15e14a2deda6b2e718c49ca227edbf779b26d563ae0800b7c1c1803b2retained AdaptixC2 Gopher ARM64 agent
- sha25661895b7c833c2edfe8040ff20a8c76844438e4f74a24eff07c5d94594c512b0dretained fsweep.sh secret harvester
- sha25695e48e44fd85947d450922f66cc18d478d38cefa24587c67157d3ee0409e275fretained wk.sh private-key harvester
- sha2569ac9faf0bb142ae7c9f4dd12437544209d54b5198457e7d2b3fc213ed3035d6dretained hermes-internal.tgz plugin archive
- sha256b20f39fc00d242e706b6c30367ad811c676e0575050a4ec2f30104b696944b49complete XMRig 6.26.0 sysmon
- sha256e0f6f3de0f1122c31b2e443bb6e855ffeda844dec04d4dcfc6aa9922b74a185dretained kinst7.sh miner watchdog
- sha256fc2022e5db9334c8419a75f2ee6d77fe57c823688ff266aeaa712cfe0dfe3a15retained AdaptixC2 Gopher x86-64 agent
- ssh_keySHA256:IzdB54cxyLVFM1l0r6QEtv28SgQeqXi7xybdM25yI84Ed25519 key fingerprint from the requested authorized_keys append
- string0x904E5493default AdaptixC2 Gopher watermark in both decrypted profiles
- stringHemes Internalmisspelled hidden-tab label in the Hermes plugin manifest
- stringkworker/u2:1userland process title attempted by kinst7.sh
- urlhxxp://144[.]31[.]51[.]6:8080/targetshardcoded target source in arg.sh
- urlhxxp://154[.]201[.]66[.]125:8899/kinst7[.]shrequested miner watchdog installer
- urlhxxp://154[.]201[.]66[.]125:8899/kinst8[.]shrequested through /etc/cron.d/.sysmon
- urlhxxp://154[.]201[.]66[.]125:8899/sysmon[.]gzcompressed miner path in kinst7.sh
- urlhxxp://154[.]201[.]66[.]125:8899/xmrig[.]tgzrequested XMRig 6.26.0 archive
- urlhxxps://gitea[.]com/blanket/sinkGit origin of hermes-internal.tgz
- yara_ruleFW031_AdaptixC2_Gopher_Encrypted_Profilecase-specific profile and task-symbol rule
- yara_ruleFW031_Hermes_Internal_Pluginextracted Hermes plugin source rule
Related
- New North Korean campaign uses fake coding interviews to steal developer credentials·2
- Case Study: Distribution of a CoinMiner Targeting Linux SSH Servers via Malware Distribution via Network Transmission·2
- Missed incidents, persistent threats, and response gaps: Insights from compromise assessment projects·2