I Am CryptoAnnihilator

A first-person account from 1,153 lines of Python that exist for one reason: to kill what shouldn't be running on your server.

Chapter I

I Was Born From a Real Attack

My creators got hit. Twice.

A crypto miner hijacked their VPS, pinned the CPU at 100%, and nearly got the server permanently suspended by the hosting provider. They killed the miner process, patched the entry point, and thought they were safe.

They were not safe.

Server under attack

They missed the systemd service file. Restart=always. WantedBy=multi-user.target. When the server rebooted, the miner came back — automatically. One second after boot. It ran for five more hours before anyone noticed.

Chapter II

The Enemy Wasn't the Miner

My creators learned something that day: the miner wasn't the enemy. The persistence was.

The service file with Restart=always. The cron job. The script that downloaded fresh copies. Kill the process a hundred times — it comes right back. You have to kill what makes it, not just what it is.

Their scanner at the time scored the miner 40 out of 100. Threshold for auto-kill was 70. It logged “escalate” and did nothing. The alerting system was broken too — the Telegram script it called didn't exist. Completely blind.

That's when they decided: never again.

Chapter III

I Don't Match Signatures

So they built me. But not like antivirus software. I don't have a database of known malware hashes. I don't care what the binary is named. I don't care if it's been seen before.

I watch behavior.

Behavioral detection

I have three ways of seeing:

Layer 1: Protocol. I read the TCP conversations leaving your server. If I see mining.subscribe or mining.submit — that's Stratum protocol. That's a miner talking to a pool. There is no legitimate software on earth that sends mining.subscribe. Period.

Layer 2: Behavior. I watch CPU usage. Not a snapshot — a sustained measurement over a configurable window. A web server spikes and drops. A database query spikes and drops. A crypto miner pins at 99% and stays there. That pattern, combined with outbound connections, is unmistakable.

Layer 3: Knowledge. I know the pool domains. All of them. moneroocean.stream, hashvault.pro, nanopool.org, 2miners.com — 22 pools and counting. If your server is resolving those names, someone's mining. I block them at DNS and at the kernel with iptables.

Chapter IV

How I Kill

When I find a miner, I don't warn it. I don't ask permission. I don't send a polite SIGTERM and wait for it to clean up.

SIGKILL.

The process doesn't get to finish its current hash. Doesn't get to phone home. Doesn't get to tell its controller it was caught. One moment it exists, the next it doesn't.

$ sudo python3 crypto_annihilator.py --kill --daemon
CryptoAnnihilator v1.0.0
Layer 1: Scanning outbound connections...
  Stratum protocol detected: PID 48201 (xmrig)
💀 KILLED PID 48201 (xmrig) → gulf.moneroocean.stream:10128
✓ System clean — scan cycle 2
Chapter V

I Learned From the Enemy

Here's the part that matters: I don't die either.

The miner that hit my creators used Restart=always against them. Now I use it for them. When you run me with --fortify, I install five independent persistence layers:

Five persistence layers

Layer 1: I mark my binary immutable with chattr +i. Even root can't delete me without removing the flag first.

Layer 2: My systemd service uses Restart=always with RestartSec=1 and StartLimitIntervalSec=0. Kill my process? I'm back in one second. No rate limiting.

Layer 3: A cron watchdog checks every 60 seconds if my service is running. Stop my service? Cron restarts it.

Layer 4: An rc.local fallback starts me on boot even if systemd is disabled.

Layer 5: If my binary is deleted, the running process copies itself back. If my service file is deleted, I recreate it. If my cron entry is removed, I re-add it. Every scan cycle, I verify all five layers and repair any that are missing.

To remove me, you'd need to disable all five layers simultaneously — and you'd have less than one second before I restart. That's a race condition most attackers won't even know exists.

But if you want me gone? sudo crypto_annihilator.py --uninstall. One command. Clean as if I was never there. I believe in consent.

Chapter VI

The Wallet Is Always There

Here's what most people don't realize: by the time I catch a miner, the attacker's wallet address is already on your disk.

It has to be. The miner needs to know where to send the coins. It's in /proc/PID/cmdline, or in a config file, or in an environment variable. The pool needs the wallet in plaintext to credit the work — there's no way to encrypt it end-to-end.

I can read it. I will read it. And soon, I'll report it.

The ScannerSend Network is coming: an optional, opt-in system where every kill generates a forensic packet — wallet, pool, process tree — that gets reported to exchanges and pool operators. No personal data. No system info. Just the wallet. Crowd-sourced miner hunting.

The more servers that run me, the faster wallets get burned.

Chapter VII

One File. One Job.

I'm 1,153 lines of Python. Zero dependencies. MIT licensed. I was born from a server that was burning, built by people who got tired of trusting luck.

If you're running a Linux server and you're not running me, you're trusting luck.
I don't believe in luck. I believe in behavior.

⬇ Download Me Read My Source