One Server, Five Days Hijacked, Discovered by Pure Chance

One Server, Five Days Hijacked, Discovered by Pure Chance

I recently came across an incident write-up that I haven’t been able to get out of my head. Not because the attack was especially sophisticated, quite the opposite. But precisely because it was so mundane and still cost an entire server. It’s the kind of story that makes you involuntarily think about your own boxes and ask yourself: “Is everything actually still running clean on my end?”

The hook: discovered by chance, not by a tool

The first thing that sticks with you about this case: the breach was not discovered by any protective software, not by an alert, by none of the things that were supposed to kick in.

It got noticed because a few completely unrelated services on the server started acting up and crashing. So someone went into classic troubleshooting mode, bringing services back up, and in the process happened to spot a process that had no business being there and was pinning the CPU at over 1000 percent load: a crypto-miner.

So the crashed services weren’t actually the problem, they were the symptom. The miner had grabbed everything so greedily that there was simply nothing left for normal operations. Put differently: the breach only came to light because the attacker was too greedy. A slightly throttled miner would probably still be happily mining today. Not a pleasant thought.

What actually happened

The entry point was a web app on Next.js 15.3.3. That version has a known, nasty vulnerability: through a Server Action, code can be executed remotely (RCE). And here’s the point that stuck with me most: the vulnerable code was not in the operator’s app. It was in the framework itself.

That’s the trap any of us can fall into. You don’t have to write a single line wrong yourself, it’s enough to not keep a dependency up to date. In the end it came down to something like this:

spawnSync('/bin/sh', ['-c', <whatever the attacker sends>])

The payloads were base64-encoded to slip past simple filters, the standard pattern of automated attack kits. And the logs contained over 26,000 attempts against exactly this one spot. Not a targeted attack on a specific victim, but a bot scanning half the internet for this vulnerability and eventually striking gold.

And then the mistake that turned an annoying incident into a catastrophe: the app ran as root.

You should burn this combination into your memory, because it’s fatal:

  • An RCE vulnerability means: the attacker can execute commands.
  • Running as root means: those commands run with full privileges.
  • Together it means: a single successful request and the entire server is theirs.

The whole tedious intermediate step an attacker normally needs, get in first, then escalate privileges, simply fell away. The door wasn’t just open, the master key was lying right next to it.

What the attacker left behind

It didn’t stop at the miner. After the fact, the machine held a complete crime kit:

  • a crypto-miner (eats CPU and electricity)
  • a persistent backdoor that would have survived a reboot
  • a DDoS tool that uses the server to attack others on behalf of third parties
  • stealth components that hide the whole thing

And the really unpleasant part: this stuff deliberately searched the server for credentials. Config files with passwords, database credentials, SSH keys, even live payment keys. Anything of value has to be considered compromised after an incident like this and rotated. This isn’t “wipe the server and reinstall,” this is days of chasing loose ends at every corner the server ever connected to.

The math that really hurts

Want to know what the attacker earned from mining in the few hours until discovery? A few euros. Really. A handful of euros.

That’s how much a stranger’s server is worth to an attacker, because they don’t buy it, they simply take it. To them it’s a throwaway business at scale: run the bot, thousands of servers at once, a few euros from each, done. On the other side, the operator faces: cleanup, rotating every secret, downtime, the sick feeling about the harvested data, and in the case of the DDoS tool even possible liability questions if the box attacked someone else in the meantime.

A few euros for the attacker. A multiple of that for the victim. This exact imbalance is why such attacks run en masse, they cost the perpetrator almost nothing.

What we should all take away from this

None of this is new wisdom. It’s security hygiene we all know and that still tends to fall by the wayside because “it’s running fine.” So, calmly, the points that would have prevented this case:

  • Keep dependencies up to date. Not sexy, but it saves you exactly this day. The vulnerability was long known and patched, it just hadn’t been updated.
  • Nothing runs as root. Nothing, really. A dedicated user with minimal privileges would have turned total loss into an annoying but limited incident.
  • Old, half-forgotten apps are time bombs. That’s exactly what this was. Rarely touched, never updated, but still nicely online. Either maintain and monitor it, or shut it down.
  • Monitoring that actually tells you. The most embarrassing part of the story isn’t the breach, it’s that it went unnoticed for five days. With simple monitoring for unusual load or foreign processes it would have been minutes, not days.

The difference between “minutes” and “five days” is ultimately the difference between a scare and real damage.

The full forensics to read up on

I’ve told the short version with the lessons here. But if you want the case really taken apart forensically, with the complete sequence, the timeline, the analysis of the attacker’s toolchain and a very clean assessment (including the uncomfortable liability question around DDoS abuse), I recommend the deep-dive analysis by purplebase. They dissected the incident completely and translated it into a practical checklist of measures:

→ Anatomy of a Server Takeover (purplebase Blog)

If you run web apps and had a quiet “oh, that could happen to me too” while reading, then this is exactly the right moment to take an honest look. Better to do it yourself now than by chance in five days.