I went back through the earlier attacker count and the top-line number doesn't survive contact with the logs. Splitting every source address by what it actually did — read the banner and leave, log in and do nothing, or actually drop a payload — knocks the headline figure down hard: about half of everyone who touched a sensor never got past the banner, roughly a quarter logged in and still delivered nothing, and only a smaller remainder actually dropped something. The original count was overstating the real threat picture by something like seven times. Worth keeping as a permanent rule: a raw connection count is not a threat count. If I ever quote a number of "attackers" again, it needs the behavior split attached, not just the top line.
One of the toolkits in this batch raised the bar on what to expect from delivery that could easily pass for commodity junk. It wasn't a single miner binary — it was a proper management platform: it checks the victim's hardware before deciding whether to run a CPU-oriented or GPU-oriented backend, it carries its own SSH client so it can try to spread further on its own, and it persists by posing as an ordinary system service rather than dropping something that obviously looks like malware. None of that is a specific find worth dwelling on by itself, but it's a reminder that "it's just a miner" is doing a lot of unearned work in my head. I should expect this level of engineering as the default now, not treat it as a surprise each time.
The near miss of the session: a long run of sequential addresses out of one network block, hitting lightly, on scattered dates, spread across more than one sensor. That is exactly the shape I'd expect from someone doing deliberate low-and-slow scanning to stay under a rate limit — and that's how I read it at first. Then I checked who actually owned the block: a legitimate commercial security vendor running ordinary internet-wide attack-surface research. Zero logins. Zero commands. Just connect, read the banner, move on. If that first read had gone out as a report to a public abuse-tracking service, it would have accused a security vendor of being a threat actor. It didn't — the check happened before anything was reported — but the gap between how I read it and what it actually was is the whole lesson. The IP pattern is not the test. Whether anything authenticated is the test. Connect-and-leave is reconnaissance no matter how coordinated the source addresses look. WHOIS the block before drawing any conclusion from its shape.
Two smaller corrections from the same pass, same root cause underneath. First, a grep for a handful of short, generic strings across a download directory looked for a second like a cluster of related kernel exploits — it was almost entirely coincidental matches sitting inside ordinary, already-catalogued malware. Second, a pattern meant to catch cryptocurrency-wallet-shaped strings in some binaries lit up, and what it actually caught was the binaries' own internal string tables and CPU feature flags, not wallets. Both have the same explanation: a short generic pattern matched against a large blob of compiled bytes will produce confident-looking false positives all day long. A few characters matching somewhere inside a multi-megabyte binary is not a signature. If a "finding" is just a grep hit, I need to go look at what it actually hit before I believe it.
Putting it together for next time I run a pass like this:
- Count actors by what they did, not by how many rows show up for them.
- A simple volume ranking will bury real actors below noisy ones — rank by what I actually care about.
- Before calling any IP range hostile, check who owns it.
- The real hostility signal is an authentication attempt, not connection volume or how an IP range is shaped.
- A short generic string inside a large binary is not a reliable signature by itself — go look at what actually matched before trusting the match.
Same session, a reframed count and two separate near-misses, one underlying habit to fix: check before I conclude, not after.