Home/ Blog/ Security news/ Article
Blog · Security news

A BGP hijack pushed a malicious Virtualizor update that ran as root. Check for one systemd service.

A 33-hour BGP hijack redirected Softaculous update traffic and pushed a malicious Virtualizor package that ran as root. Check a systemd service, patch 3.2.9.9.

Isometric server cluster with one supply conduit forking into a shadowed side structure

Your software updater trusts two things: that the connection is encrypted, and that the server on the other end is who its certificate claims to be. Between August 28 and 30, an attacker showed why that is not enough. By hijacking the internet routes to Softaculous, the company behind the Virtualizor hypervisor panel, they served a booby-trapped update over a valid encrypted session to a small number of servers, and the update ran as root. No password was cracked and no software bug was exploited. The delivery channel itself was the way in.

This is a supply-chain compromise, but not the kind that hides malware inside a package on a registry. Here the package was fine until the moment of delivery. The attacker sat in the middle of the download, swapped the file, and let the operator's own updater install it with full privileges. For anyone who runs a control panel that auto-updates, that is a more uncomfortable failure than a normal CVE, because there was nothing on your host to patch in advance.

Softaculous update-channel hijackAug 28, 20:57 UTC: Hijack begins. Aug 30, 06:10 UTC: Route restored. Sep 1: 3.2.9.9 fix.Softaculous update-channel hijackAug 28, 20:57 UTCHijack beginsAug 30, 06:10 UTCRoute restoredSep 13.2.9.9 fix
Source: Virtualizor security advisory; BleepingComputer.

What actually happened

According to Virtualizor's own advisory, an attacker announced a route for 162.55.80.0/24, a block of Hetzner address space that Softaculous uses for update and billing systems. Per the advisory, the rogue announcement was carried via AS62390 (NexonHost) and transit provider AS6204 (Zet.net); it does not attribute intent to those networks, which sit on the path a hijack abuses. The diversion ran from 20:57 UTC on August 28 to 06:10 UTC on August 30, roughly 33 hours, in two waves separated by a lull. During those windows, any Virtualizor install that phoned home for an update could have reached the attacker's server instead of the real one.

Servers that took an update during a diverted interval received a poisoned package. The known indicator of compromise is a systemd unit at /etc/systemd/system/java-jre-update.service with a matching running service. The vendor says only a small number of installs were hit, a scope BleepingComputer's reporting frames as a limited set of servers rather than the wider user base. It also states plainly that it cannot produce a definitive victim list, because the malicious responses came from the attacker's system and never touched Softaculous logs. If you run Virtualizor and checked for updates in that window, "probably fine" is the best assurance the vendor's data can give you. That is why the check below is on you, not on them.

Why the encrypted connection did not save anyone

The reflex answer to "someone tampered with my download" is "but it was over HTTPS." It was. That did not matter, and understanding why is the whole lesson here.

Transport encryption authenticates the pipe, not the thing flowing through it. When routing is hijacked, the attacker controls the destination the client resolves to, so it can present a valid certificate for a host it now answers for and complete a clean handshake. The client sees a green connection to the right name and hands over trust. Nothing in that exchange verifies that the bytes of the update file are the bytes the vendor built. Only a signature over the artifact itself does that, checked with a key the client already holds. By Virtualizor's own account, its updater did not check any package signature, so a swapped file was accepted without complaint. Transport security was standing in for package integrity, and the two are not the same control.

We have watched this exact substitution fail before in different clothes. A "signed" npm release shipped malware with valid provenance because the checkmark proved where a build ran, not that the code was safe. Browser extensions that turned into wallet drainers did so through the trusted auto-update channel, not a new install. A hijacked shared ad script swapped crypto addresses in visitors' browsers with no code review to catch it. Verifying the pipe, the badge, or the source repo is not verifying the payload that lands on the box.

One detail the wire coverage skipped: the route looked legitimate

Most reports noted the hijack and moved on. The mechanism deserves a closer look, because it defeats the cheap version of route monitoring. The rogue announcement left Hetzner's own AS24940 sitting at the end of the route, so the prefix still looked like it came from its rightful owner. A monitor that only alerts on an origin-AS mismatch, which is the most common free tier of BGP alerting, would not necessarily fire. Catching this needed path-aware validation and route origin authorization (RPKI ROV) that rejects an announcement from an AS not authorized to carry the prefix, regardless of what origin the path claims. If your alerting on your own prefixes is origin-only, this incident is a reason to check whether it would have caught a forged path.

Patching the vendor's bug does not close your window

Virtualizor shipped 3.2.9.9 on September 1 with a mitigation tool, and it says package signing is coming. Both are the right fixes. Neither helps a server that already took an update during the 33-hour window. Signing protects the next update; it does nothing about code that ran as root three days ago. This is the difference between patching and knowing, and it is the part of the story an operator has to own.

The exposure is the gap between "an unverified update ran as root" and "someone noticed." Close it by hunting the aftermath, which shows up as ordinary persistence rather than anything exotic. A poisoned update that runs as root leaves the same fingerprints any root-level intruder does: a new systemd unit you did not deploy, SSH keys you did not add, cron entries you did not write, and outbound connections to somewhere you do not recognize. Host telemetry catches all of that whether or not your vendor ever signs a package, which is the point. You cannot prevent a route hijack from your rack, but you can see what it left behind.

Why a hypervisor panel makes this worse

The blast radius is what separates this from a poisoned update to some leaf application. Virtualizor is a control plane: a single master manages many virtualization nodes across KVM, Xen, LXC, OpenVZ, and Proxmox, and hosting providers use it to run fleets of customer VPS instances. An update to that software runs as root on the machine that holds the keys to all of them. Poisoning the updater of a management tool is therefore categorically worse than poisoning an ordinary app, because the payload lands at the top of the stack with the credentials to reach everything below it. The uncomfortable follow-on question for any provider: if the master was reachable, what could the payload have done to the guests it controls?

The practical takeaway is that update-channel integrity on infrastructure-management software deserves more scrutiny than you would give a normal package. These are the tools that, when they auto-update as root, can hand an attacker the whole environment in one move. This joins a run of stories where the distribution channel, not the code, was the attack surface, and where the industry's answer has been to slow and harden delivery, as when GitHub and PyPI added release cooldowns to blunt poisoned packages.

What to check today if you run Virtualizor

Treat any install that could have auto-updated between August 28 and 30 as needing a look, not just the ones you know updated. The vendor's advisory lists the concrete steps; the order below puts detection first, because that is the part that tells you whether you were actually hit.

  • Look for /etc/systemd/system/java-jre-update.service and a running service by that name. Its presence is the known sign of compromise.

  • Hunt for persistence you did not put there: unfamiliar SSH keys, extra local accounts, unexpected cron or timer jobs, and traffic leaving the box to hosts you cannot place.

  • Run the scanning tool the vendor ships and move the install to 3.2.9.9.

  • Rotate every Virtualizor API key, lock API access down by source address, and reissue the Client Center keys.

  • Reset client-area passwords, and if anyone entered card details during the window, tell them to watch their statements.

The larger fix is not a version number. It is treating the update path as a trust boundary you have to verify yourself: check that the software you depend on signs its artifacts, and where it does not yet, make sure your host monitoring would catch what a bad update leaves behind. This one hit a niche panel and a small number of servers. The delivery-channel weakness it exploited is not niche at all.

Topics

Frequently asked questions

What happened in the Virtualizor BGP hijack?

An attacker hijacked the internet routes for Softaculous update infrastructure between August 28 and 30, 2026, and served a malicious Virtualizor update to servers that checked for updates during the roughly 33-hour window. The poisoned package ran as root because update clients did not verify package signatures.

How do I know if my Virtualizor server was compromised?

Check for a systemd unit at /etc/systemd/system/java-jre-update.service and a matching running service, the known indicator of compromise. Also audit for SSH keys, accounts, and cron jobs you did not create, and review outbound connections. The vendor cannot produce a definitive victim list.

Why did HTTPS not stop the malicious update?

Transport encryption authenticates the connection, not the file. A route hijack lets an attacker answer for the real hostname and present a valid certificate, so the handshake looks clean. Only a signature over the update package itself proves the bytes are the vendor's, and those clients did not check one.

Does updating to Virtualizor 3.2.9.9 fix the problem?

Version 3.2.9.9 adds a mitigation tool, and the vendor says package signing is coming. Both protect future updates. Neither removes malware from a host that already installed a poisoned update during the hijack window, so you still need to hunt for the persistence it left behind.

Could BGP monitoring have caught this hijack?

Not the simplest kind. The rogue announcement kept Hetzner's AS24940 as the apparent origin, so an alert keyed only on origin-AS mismatch might not fire. Catching a forged path needs route origin authorization (RPKI ROV) that rejects announcements from an AS not allowed to carry the prefix.

Why is a compromised hypervisor panel especially serious?

Virtualizor is a control plane: one master manages many virtualization nodes and customer VPS instances. An update to it runs as root on the machine that controls the whole fleet, so a poisoned update lands with the privileges to reach every guest below it, not just one host.

Ready to meet the Guardians?

Deploys fast - agentless for monitoring and cloud, a lightweight agent for deep endpoint security. Just Suriq, standing watch.