Virtualizor Supply Chain Compromise: 33 Hours of Hijacked Routes and Unsigned Updates
By Sethu Satheesh · 2 Sept 2026 · 19 min read
Threat Actor: Unattributed · Target: Virtualizor VPS management installations; Softaculous client and billing portal users
Source: www.virtualizor.com
Executive Summary
Between 20:57 UTC on 28 August 2026 and 06:10 UTC on 30 August 2026, an attacker took control of where the internet sent traffic destined for Softaculous. For roughly 33 hours across two waves, requests for Virtualizor software updates, the Softaculous client area and the Softaculous billing portal were delivered to a server the attacker operated rather than to Hetzner-hosted infrastructure belonging to the vendor.
The mechanism was a BGP hijack. AS62390 (NexonHost), transiting through AS6204 (Zet.net), announced 162.55.80.0/24 — a slice of Hetzner address space containing Softaculous systems. Because that announcement was more specific than Hetzner's own 162.55.0.0/16, standard BGP route selection preferred it on every network that accepted it. The announcement retained AS24940, Hetzner's own autonomous system number, in the origin position, so to any observer the route appeared to come from its rightful owner.
Two things then failed in sequence, and each was independently sufficient to stop the attack.
The first was transport authenticity. Because the hijack also captured Let's Encrypt's automated domain validation traffic, the attacker obtained a genuine, publicly trusted TLS certificate for virtualizor.com, api.virtualizor.com and files.virtualizor.com. Clients connecting to the attacker's server saw no warning, because there was nothing wrong to warn about — the certificate was real, issued by a real certificate authority, to someone who could demonstrate control of the domain, because for 33 hours they genuinely could.
The second was artefact integrity. Softaculous states the position directly: "Our product update clients did not yet cryptographically verify update packages, so a modified package would not have been rejected on that basis." A malicious Virtualizor update was served to installations whose update checks happened to traverse the attacker's server during the window, establishing persistence via a systemd unit at /etc/systemd/system/java-jre-update.service. On a Virtualizor host, that means root on a hypervisor — and therefore a position above every virtual machine it runs.
The vendor characterises the outcome as affecting "a handful of servers rather than the general Virtualizor user base." In the same advisory it states that because the malicious responses were served by the attacker's system and never reached Softaculous logs, it "cannot produce a definitive list" of affected installations. Both statements are honest; they are also in tension, and this paper treats the scope as unquantified rather than small.
This paper adds one finding not present in the reporting to date. Hetzner had published a Route Origin Authorisation for 162.55.0.0/16 with a maximum length of 16 — a signed statement that no more-specific prefix from that block is authorised. Verified against live RPKI data, 162.55.80.0/24 evaluates as invalid regardless of which autonomous system announces it, including Hetzner's own. The defence against this specific announcement was published, correct, and in place. It was ignored by the majority of the internet, which carried the route anyway.
Verification of Claims
Claim: A BGP hijack diverted Softaculous traffic between 28 and 30 August 2026.
→ Verified — Stated in Softaculous's own advisory of 31 August 2026, with the window given as approximately 20:57 UTC on 28 August to 06:10 UTC on 30 August. Independently corroborated by RIPE RIS routing history for 162.55.80.0/24, which records the more-specific /24 appearing on 29 and 30 August 2026 against a baseline in which only 162.55.0.0/16 is announced.
Claim: The hijacking announcement retained Hetzner's AS24940 in the origin position. → Verified — Stated by the vendor, and consistent with RIPE RIS data, which records AS24940 as the only origin observed for the prefix during the period. AS62390 does not appear as an origin in the collector record, which is the expected result when the origin field is forged.
Claim: The attacker obtained a valid TLS certificate for Virtualizor domains. → Verified — The vendor states the attacker obtained "a technically valid TLS certificate for our domains" because "the certificate authority's automated domain-ownership validation was also routed through the hijack." This is the documented, expected behaviour of domain-validated issuance under a routing compromise, not a failure of the certificate authority.
Claim: Virtualizor update packages were not cryptographically signed. → Verified — Stated directly by Softaculous: "Our product update clients did not yet cryptographically verify update packages, so a modified package would not have been rejected on that basis." The vendor has committed to implementing package signing.
Claim: The compromise affected only a handful of servers. → Unverified — This is the vendor's characterisation, and it may prove correct. It is not currently supportable, because the same advisory states that the malicious responses never reached Softaculous's logs and that the company "cannot produce a definitive list" of affected installations. The vendor also instructs every Virtualizor operator to treat their server as in scope for checks, which is guidance appropriate to unknown rather than small exposure. Community reports from hosting operators describe finding multiple compromised hypervisors within single fleets. No verified count exists.
Claim: Route Origin Validation could not have prevented this hijack because the origin was forged.
→ False — This inference is reasonable in general and wrong in this case. Forged-origin hijacks do defeat origin comparison, but RPKI validation also enforces the maximum prefix length declared in the Route Origin Authorisation. Hetzner's ROA for 162.55.0.0/16 specifies a maximum length of 16, meaning no more-specific prefix is authorised from that block. Verified against live RPKI validation data on 2 September 2026, 162.55.80.0/24 returns invalid_length for both AS24940 and AS62390. Any network performing Route Origin Validation and discarding invalid routes would have rejected the hijacked announcement. (This paper's check was performed after the incident and confirms the ROA as published at the time of writing; it does not independently establish the ROA's contents during the hijack window, although Hetzner is a long-standing RPKI publisher and the authorisation covers its entire /16.)
Claim: The malicious update's full capabilities are known. → Unverified — No public technical analysis of the payload beyond its persistence mechanism has been published at the time of writing. What the implant does after establishing root persistence — collection, lateral movement, command and control — is not described in the vendor advisory or in any reporting located.
Claim: The attacker has been identified. → False — No attribution has been offered by the vendor, by any security research organisation, or by any government. The autonomous systems involved in the announcement are known; who directed the announcement is not.
Timeline
| Date / time (UTC) | Actor | Event | Source |
|---|---|---|---|
| 2026-08-28 20:57 | AS62390 (NexonHost) | Begins announcing 162.55.80.0/24 via AS6204 (Zet.net), origin field set to AS24940 |
Softaculous |
| 2026-08-28 → 08-29 ~08:50 | — | First hijack wave; reported to Hetzner | The Register |
| 2026-08-29 | Let's Encrypt | Domain validation traffic routed through the hijack; attacker obtains valid certificates for virtualizor.com, api.virtualizor.com, files.virtualizor.com | Softaculous |
| 2026-08-29 | Attacker | Malicious Virtualizor update package served to installations whose update checks traverse the diverted path | Softaculous |
| 2026-08-29 20:00 → 08-30 ~05:50–06:10 | AS62390 | Second hijack wave; route ultimately withdrawn | The Register |
| 2026-08-29 / 08-30 | RIPE RIS | Collector data records the more-specific /24 present during both windows | RIPE (this paper's query) |
| 2026-08-31 | Softaculous | Publishes advisory "Security Incident – BGP Hijacking"; fraudulent certificate reported for revocation | Virtualizor |
| 2026-09-01 | Softaculous | Releases Virtualizor 3.2.9.9 with a Security Analyzer tool in the admin panel | Virtualizor |
| 2026-09-01 | Press | The Register and BleepingComputer publish; incident becomes widely known | Press |
Total hijack duration is approximately 33 hours across the two waves.
Attack Anatomy
Initial Access — Announcing Someone Else's Addresses
The attack begins outside the victim's estate entirely. Nothing at Softaculous was breached to start it.
BGP has no native authentication. A network announces the address blocks it can reach, and its neighbours propagate that announcement to theirs. Whether the announcement is truthful is not something the protocol establishes.
The attacker's announcement was constructed to win two separate contests at once.
Specificity. Hetzner announces 162.55.0.0/16. The attacker announced 162.55.80.0/24, a 256-address slice of it. BGP route selection prefers the longest matching prefix before it considers anything else, so on any network that accepted both, the /24 won automatically. This is the reason hijackers announce slices rather than whole blocks.
Apparent legitimacy. The announcement retained AS24940 — Hetzner's own autonomous system number — in the origin position, with the attacker's AS62390 appearing earlier in the path. To an observer comparing the origin against expectations, the route looked like it came from Hetzner. RIPE RIS collector data reflects exactly this: querying routing history for the prefix across the incident window returns AS24940 as the only origin recorded, with AS62390 absent.
Technique mapping (this paper's assessment): T1584.005 Compromise Infrastructure: Botnet is not applicable; the closest published mapping is T1557 Adversary-in-the-Middle, achieved at the routing layer.
Certificate Acquisition — Domain Validation Believes Routing
With traffic for the Softaculous addresses arriving at the attacker's server, the attacker requested certificates from Let's Encrypt for the Virtualizor domains.
Domain-validated issuance works by asking the requester to prove control of the domain, typically by serving a specific response at a specific location on it. The certificate authority makes that request over the internet — which means the answer to "who controls this domain" is decided by whoever the routing table currently sends the validation request to.
For 33 hours, that was the attacker. The certificates issued were genuine. They were not forged, stolen, or mis-issued in any sense a certificate authority could have detected: the requester demonstrably controlled the domain at the moment of validation.
This is the part worth sitting with. Clients connecting to the attacker's server were shown a valid certificate chain for the correct hostname, and every TLS verification passed, because everything TLS verifies was true. The compromise was one layer below the thing TLS is designed to establish.
T1557 Adversary-in-the-Middle; T1553.004 Subvert Trust Controls: Install Root Certificate is not applicable — no trust store was modified, which is precisely what makes this harder to detect.
Delivery — Nothing Left to Check
An update client fetching a package now had a correctly resolved hostname, a valid TLS connection, and a genuine certificate. Every check it performed returned true.
The one check that would have failed was the one not being performed. Softaculous states the position without hedging: update clients did not cryptographically verify packages, so a modified package would not have been rejected on that basis.
Package signing is the control that survives a compromised transport, because it does not depend on the transport. A signature made with a key the vendor holds offline is verifiable by the client regardless of who served the bytes. Without it, the entire integrity guarantee rests on the network path, and the network path was the thing under the attacker's control.
T1195.002 Compromise Software Supply Chain.
Persistence — Root on a Hypervisor
Installations that pulled the malicious update during the window received an implant that persisted through a systemd unit at /etc/systemd/system/java-jre-update.service — a name selected to survive a quick reading of a service list.
The privilege context matters more here than in most compromises. Virtualizor is VPS management software; it runs on hypervisors, as root. Root on a hypervisor is not one compromised host, it is a position above every guest that hypervisor runs, and for a hosting provider those guests belong to customers who have no relationship with Softaculous and no way of knowing any of this happened.
T1543.002 Create or Modify System Process: Systemd Service.
Collateral — The Billing Portal
The diverted address block carried more than the update endpoint. The Softaculous client area and billing site were also routed through the attacker.
Anyone who signed in during the window presented credentials to the attacker's server over a connection that appeared entirely legitimate. Softaculous advises resetting client-area passwords for anyone logged in during the incident, reviewing card statements for anyone who entered payment details, and regenerating client-area API keys.
T1056 Input Capture; T1078 Valid Accounts.
Threat Actor Profile
No attribution has been offered by anyone.
What is known is limited to routing facts. The announcement originated from AS62390, registered to NexonHost, and reached the wider internet through AS6204, Zet.net. Whether either network was complicit, compromised, or simply a transit path that accepted an announcement it should have filtered, has not been publicly established, and the distinction matters legally and practically.
The operational profile suggests planning rather than opportunism. The prefix chosen contained software update infrastructure specifically. The attacker was positioned to obtain certificates and serve a modified package immediately, which implies the payload was prepared in advance of the hijack rather than assembled during it. The two-wave structure — a pause after the first window was reported to Hetzner, then a resumption — suggests an operator monitoring the response.
Against that, the duration is unusually long. Thirty-three hours is a great deal of exposure for an operation that depends on not being noticed, and the vendor notes the route flapped rather than remaining continuously available, which is consistent with contested propagation rather than a clean takeover.
This paper records no attribution. The incident is four days old at the time of writing, and this section should be expected to change.
Technical Indicators
Defanged where applicable. Sourced from the vendor advisory of 31 August 2026 and from this paper's own routing and RPKI queries.
Routing
Hijacked prefix 162.55.80.0/24
Legitimate block 162.55.0.0/16 AS24940 (Hetzner)
Announcing AS AS62390 (NexonHost)
Transit AS AS6204 (Zet.net)
Origin in path AS24940 (forged — the legitimate origin)
Window 2026-08-28 20:57 UTC → 2026-08-30 06:10 UTC
RPKI state (queried 2026-09-02)
ROA 162.55.0.0/16, maxLength 16, origin AS24940
162.55.80.0/24 announced by AS24940 → invalid_length
162.55.80.0/24 announced by AS62390 → invalid_length
Conclusion: the hijacked announcement was RPKI-invalid on its face
Host indicator
/etc/systemd/system/java-jre-update.service
The vendor asks operators who find this NOT to delete it immediately, but to
preserve it and make contact, so that evidence is not destroyed before the
payload has been analysed.
Affected domains (attacker held valid certificates)
virtualizor[.]com
api.virtualizor[.]com
files.virtualizor[.]com
Operator checks recommended by the vendor
Run the Security Analyzer in Virtualizor 3.2.9.9
Rotate and restrict Virtualizor API credentials
Audit for unauthorised SSH keys and accounts
Inspect scheduled tasks and outbound connections
Regenerate client-area API keys
Reset client-area password if logged in during the window
Review card statements if payment details were entered during the window
Legal and Regulatory Response
At the time of writing — four days after the hijack ended and two days after public disclosure — there is no regulatory or law enforcement response to record.
Government directives. None located. No advisory has been issued by CISA or any equivalent national body. No CVE has been assigned, and none would ordinarily apply: the incident was a routing compromise and a missing integrity control, not a defect in software that a vulnerability identifier describes.
Law enforcement. No investigation has been publicly confirmed.
Network-layer response. The hijack was reported to Hetzner during the first wave, and the route was ultimately withdrawn. The fraudulent certificate was reported for revocation. Neither action is a regulatory instrument; both are the routing and certificate ecosystems' own remedies, applied by participants.
Vendor response. Softaculous published an advisory on 31 August, released Virtualizor 3.2.9.9 with a Security Analyzer tool on 1 September, committed to cryptographic signing for all packages, and stated an intention to migrate to different infrastructure. It has told all Virtualizor operators to treat their servers as in scope for checks.
This section is expected to change, and this paper will be updated if it does. It is recorded now because the absence of official response in the first days of an incident is itself a fact about how these incidents are handled — the operators affected had the vendor's advisory and nothing else to work from.
Impact Assessment
Scope is genuinely unknown, and the vendor says so. The two statements — "a handful of servers" and "cannot produce a definitive list" — are both in the same advisory. The second is the more reliable, because it describes a structural limit on what the vendor can know: the malicious responses were served by the attacker and never touched Softaculous logs. Any operator whose host checked for updates during the window has to establish its own status.
The privilege reached is severe. Root on a hypervisor places the attacker above every guest VM it hosts. For a hosting provider, the affected parties extend to customers with no relationship to Softaculous, no notice of the incident, and no ability to check.
Detection was not available to the victims. No security control at the receiving end could have caught this. DNS resolved correctly. TLS validated. The certificate was genuine. The hostname was right. The only detectable signal was the absence of a signature check that was not being performed. This is a case where "the customer should have noticed" has no content.
The credential exposure is separate and underweighted. Coverage has concentrated on the malicious update, but the client area and billing portal were diverted for the same 33 hours, behind the same valid certificate. Anyone who logged in or entered payment details did so to the attacker.
The certificate lesson generalises beyond this vendor. Any domain-validated certificate can be obtained by anyone who controls the routing path to the validating authority for the duration of a validation request. Multi-perspective issuance, where the CA validates from several network vantage points, exists specifically to raise the cost of this and has been deployed by Let's Encrypt; the outcome here indicates it is not a complete defence against a hijack that propagates as widely as this one did.
The routing failure is the systemic one. Hetzner published a Route Origin Authorisation that made this exact announcement invalid. The route propagated anyway, reportedly reaching essentially every vantage point that receives such announcements, with roughly 72% of RIPE RIS collector peers having a best path through the attacker during active waves. The gap between "the address owner published a correct authorisation" and "the internet routed the traffic anyway" is the finding with the broadest application, because it is not specific to Softaculous, Virtualizor, or this attacker.
Lessons and Defensive Recommendations
For Network Operators
Perform Route Origin Validation, and drop invalids. This is the finding of the incident. The hijacked announcement violated a published ROA and would have been rejected by any network doing ROV with invalid-drop. Validating and then accepting invalids anyway provides no protection; the enforcement is the control.
Check your own ROAs specify a correct maxLength. Hetzner's authorisation caps at the /16, which is what made every more-specific announcement invalid. An overly permissive maxLength authorises exactly the deaggregation an attacker needs.
Monitor for more-specific announcements of your own space. RIPE RIS, RouteViews and commercial BGP monitoring will alert on a new more-specific prefix. In this case the anomaly — a /24 appearing where only a /16 had existed — is visible in public data and was detectable in near real time.
Do not rely on origin comparison alone. The origin here was forged to the legitimate AS. Anything checking only "did this come from the expected AS" would have passed it.
For Software Vendors
Sign your packages, and verify signatures in the client. This is the control that would have made the routing compromise irrelevant to package integrity. Softaculous is implementing it now; the lesson is available to everyone else before their own incident rather than after it.
Publish package hashes over an independent path. Even ahead of full signing, hashes served from separate infrastructure give clients something to compare against that a single hijack does not control.
Treat your update endpoint as the highest-value asset you operate. It has write access, as root, to every customer installation. Very few vendors defend it in proportion to that.
Log what you cannot see. The most damaging sentence in the advisory is "we cannot produce a definitive list." Client-side telemetry confirming which version each installation actually received would have converted an unbounded incident into a bounded one.
For Hosting Providers and Operators Running Virtualizor
Check for /etc/systemd/system/java-jre-update.service and, if present, preserve rather than delete it and contact the vendor — the payload has not been publicly analysed, and destroyed evidence cannot be recovered.
Treat any host that checked for updates during the window as in scope regardless of the vendor's characterisation of scale. A negative check is cheap; an unexamined compromised hypervisor is not.
Rotate credentials that were exposed to the client area or billing portal during the window, not only Virtualizor API keys.
Consider what a root compromise of the hypervisor means for your customers' guests, and whether your own disclosure obligations to them are engaged. Your customers cannot check this themselves.
For Leadership and CISOs
Your software update path is a trust relationship with a network you do not control. This incident required no compromise of the vendor and no compromise of you. It required control of the route between you, for a day and a half.
Valid TLS is not evidence of an uncompromised path. It is evidence that someone who controlled the domain at validation time obtained a certificate. Under a routing hijack, the attacker satisfies that honestly.
Ask which of your vendors sign their packages. It is a short question with a binary answer, and it distinguishes suppliers for whom a transport compromise is survivable from those for whom it is total.
Sources
- Virtualizor — Security Incident: BGP Hijacking (31 August 2026)
- The Register — 33-hour BGP hijack of Softaculous traffic prompts security scramble
- BleepingComputer — Hackers push malicious Virtualizor update in BGP hijacking attack
- CybersecurityNews — BGP Hijack Diverts Softaculous Traffic to Deliver Malicious Virtualizor Update
- RIPEstat — RPKI validation, AS24940 / 162.55.80.0/24
- RIPEstat — Routing history, 162.55.80.0/24
- Holterbach et al. — A System to Detect Forged-Origin BGP Hijacks (NSDI '24)
- RPKI documentation — Securing BGP
- Virtualizor — Internal Infrastructure Security Breach (August 2022, prior incident)
Related Research
A stranger emailed an unpaid maintainer offering to take over a package he no longer used. Three months later it was stealing private keys from bitcoin wallets holding more than 100 BTC. Nobody was ever identified.
A credential left in a Docker image layer let an unidentified attacker rewrite Codecov's Bash Uploader and harvest every secret from its customers' CI environments for sixty days. No one was ever identified.
A North Korean-linked actor compromised Trading Technologies' X_TRADER, used it to breach 3CX, and shipped signed, trojanised VoIP clients to its customers — the first documented case of one software supply chain attack causing another.