Summary
Between 28 August 2026 at approximately 20:57 UTC and 30 August 2026 at approximately
06:10 UTC, a block of IP addresses used by Softaculous services (162.55.80.0/24, part of our
infrastructure at Hetzner) was affected by a BGP hijack: an unauthorized announcement of that address space by an unrelated network, which diverted internet traffic destined for those
addresses to a server operated by an attacker. The attacker obtained a technically valid TLS
certificate for our domains, so connections affected by the hijack showed no certificate
warning.
The affected addresses served, among other systems, our software update endpoint, our
client area / billing site.
We have confirmed that a malicious Virtualizor update package was delivered to a small number of installations that checked for updates while their traffic was being diverted. This affected a handful of servers rather than the general Virtualizor user base. Because the malicious responses were served by the attacker’s system and never reached our own logs, we cannot produce a definitive list of affected servers, so every Virtualizor operator should carry out the checks in the If you run Virtualizor section. We have not
identified a malicious package for any other product; that investigation is ongoing.
Routing has been fully restored. We have reconstructed the incident minute-by-minute from public routing data; the complete measurement table is included below.
What happened
Traffic between networks on the internet is routed using BGP (Border Gateway Protocol), a
system that has historically relied on networks trusting one another’s route announcements. In a BGP hijack, a network announces IP address ranges it does not control, and traffic for those
addresses is drawn toward it.
At approximately 20:57 UTC on 28 August 2026, the network AS62390 (NexonHost) began
announcing 162.55.80.0/24 — a portion of Hetzner’s address space containing IP addresses for a number of Softaculous systems — without authorization, routed through the transit provider
AS6204 (Zet.net). This announcement was more specific than Hetzner’s normal announcement of the surrounding block (162.55.0.0/16), so under standard BGP route selection it took precedence on every network that accepted it. The announcement retained AS24940 (Hetzner) on the AS path as the apparent origin.
The attacker’s server was able to obtain a valid TLS certificate from a public certificate
authority (Let’s Encrypt) for our domains, because the certificate authority’s automated
domain-ownership validation was also routed through the hijack. Connections affected by the hijack therefore did not show a browser or client certificate warning. The certificate
covered domains across our products, including virtualizor.com, api.virtualizor.com and
files.virtualizor.com; the full list is in Appendix A.
Timeline
All times UTC. Start and end times are corroborated by public RIPE routing data, not only by
provider reports.
| When | Event |
|---|---|
| 28 Aug, ~20:57 | AS62390 begins announcing 162.55.80.0/24 without
authorization, via AS6204. Because it is more specific than the
legitimate route, it wins route selection wherever it propagates, and
traffic to the affected addresses is diverted. |
| 28 Aug ~21:00 - 29 Aug ~08:50 | First wave. The unauthorized route is accepted by essentially every internet vantage point that receives it. The route is highly unstable and flaps continuously throughout. |
| 29 Aug, ~08:00-08:50 | Active interception independently confirmed: a host on the diverted route answers for Softaculous domains using the fraudulently obtained but technically valid certificate. |
| 29 Aug, ~08:50 | After we report the hijack to Hetzner and escalate repeatedly, Hetzner begins announcing 162.55.80.0/24 directly. Diversion drops to zero within minutes. |
| 29 Aug ~09:00 - ~20:00 | Lull. Roughly 11 hours with essentially no
diversion — first because Hetzner’s direct announcement holds, then
because both the hijacked and the corrective /24 are withdrawn and traffic returns to the legitimate /16. |
| 29 Aug ~20:00 - 30 Aug ~06:00 | Second wave. The unauthorized announcement resumes for roughly 10 hours, again accepted by essentially every vantage point that receives it. |
| 30 Aug, ~05:50-06:10 | The unauthorized route is withdrawn and normal routing is restored globally. |
| 30 Aug, 06:10 onward | No further diversion observed. Verified clean in public routing data through at least 30 Aug 10:00 UTC. |
How widespread it was, and how we measured it
Method. RIPE’s Routing Information Service (RIS) operates 368 collector peers — a sample
of mostly large transit and internet-exchange networks around the world. For each 10-minute mark across the incident we retrieved the reconstructed routing table for 162.55.80.0/24 and
counted, among the peers that held a route to the prefix at that moment:
- Diverted — best path traverses AS62390 (the hijacker);
- On clean /24 — best path is a legitimate
/24(Hetzner origin, no AS62390); this only
exists once Hetzner began announcing the/24directly as a countermeasure; - Peers with no
/24route fell back to Hetzner’s normal162.55.0.0/16and were not
diverted.
The share of RIS peers whose best path traversed the hijacker is the standard proxy for the
share of the internet whose traffic to this address range was sent to the attacker. It is a
routing-topology measure, not a byte count.
What we found.
| Measure | Value |
|---|---|
| Incident window | 28 Aug 20:57 UTC -> 30 Aug ~06:10 UTC (~33.3 hours) |
| Distinct RIS peers that carried the hijacked route at some point | 368 of 368 (the entire RIS peer set) |
| Peak diversion while a wave was active | ~100% of peers holding a /24 route — median 266, range 145-272 — i.e. ~72% of the full 368-peer RIS set |
| Origin AS shown in every single snapshot | AS24940 (Hetzner) — the hijacker kept the real origin on the path tail and never appeared as origin itself |
| Time-weighted average diversion over the full 33 h | ~28% of all 368 RIS peers / ~65% of route-carrying peers, at any given instant |
| Sustained waves | Two: 28 Aug ~21:00 -> 29 Aug ~08:50, and 29 Aug ~20:00 -> 30 Aug ~06:00 |
| Gap between waves | ~11 hours of near-zero diversion (29 Aug ~09:00-20:00) |
| Route stability | Highly unstable — ~10,600 route withdrawals recorded in the window; transit-provider flap dampening repeatedly suppressed the route |
What this means in practice. Whenever the unauthorized route was propagating, a server had
roughly a 72% chance (by this proxy) that its network was sending traffic for
162.55.80.0/24 to the attacker — this was a broadly visible hijack, not a localized one,
because a more-specific announcement beats the legitimate route everywhere it reaches. However, the route flapped continuously, so for any individual server the diversion was intermittent across the roughly 22 hours the hijack was active, and there was an ~11-hour window mid-incident with almost no diversion. A Virtualizor server received the malicious package only if an update check happened to land during a diverted interval and completed — which is why only a small number of installations were affected.
Findings: full BGP-state measurements (10-minute resolution)
Reconstructed from RIPE RIS via the RIPE Stat bgp-state API, one snapshot every 10 minutes.
Column definitions
- Time (UTC) — snapshot time (
MM-DD HH:MM). - Peers with route — RIS collector peers (of 368) holding any route to
162.55.80.0/24. - Diverted (AS62390) — of those, how many had a best path through the hijacker.
- On clean /24 — of those, how many had a legitimate
/24best path (Hetzner’s
countermeasure announcement). - % of routed peers — Diverted / Peers-with-route.
- % of all 368 RIS — Diverted / 368 (lower-bound proxy for share of the internet diverted).
How to read it. Rows aligned to 00:00 and 08:00 UTC are the most reliable (RIS takes a full
table snapshot every 8 hours); values between those points can under-count because the route was flapping so hard. Multi-row plateaus and the 8-hourly rows are ground truth; isolated single-row spikes or dips are measurement noise or momentary flap states. A row showing 1 diverted / 1 with route during a wave means the route was suppressed almost everywhere at that instant (flap dampening), not that the hijack had stopped.
| Time (UTC) | Peers with route | Diverted (AS62390) | On clean /24 | % of routed peers | % of all 368 RIS |
|------------------|------------------|--------------------|--------------|-------------------|------------------|
| 08-28 20:50 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-28 21:00 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-28 21:10 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 21:20 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 21:30 | 214 | 214 | 0 | 100.0 | 58.2 |
| 08-28 21:40 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 21:50 | 262 | 262 | 0 | 100.0 | 71.2 |
| 08-28 22:00 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 22:10 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 22:20 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 22:30 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 22:40 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 22:50 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 23:00 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 23:10 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 23:20 | 7 | 7 | 0 | 100.0 | 1.9 |
| 08-28 23:30 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 23:40 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-28 23:50 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 00:00 | 269 | 269 | 0 | 100.0 | 73.1 |
| 08-29 00:10 | 270 | 270 | 0 | 100.0 | 73.4 |
| 08-29 00:20 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-29 00:30 | 272 | 272 | 0 | 100.0 | 73.9 |
| 08-29 00:40 | 272 | 272 | 0 | 100.0 | 73.9 |
| 08-29 00:50 | 272 | 272 | 0 | 100.0 | 73.9 |
| 08-29 01:00 | 272 | 272 | 0 | 100.0 | 73.9 |
| 08-29 01:10 | 11 | 11 | 0 | 100.0 | 3.0 |
| 08-29 01:20 | 272 | 272 | 0 | 100.0 | 73.9 |
| 08-29 01:30 | 266 | 266 | 0 | 100.0 | 72.3 |
| 08-29 01:40 | 259 | 259 | 0 | 100.0 | 70.4 |
| 08-29 01:50 | 260 | 260 | 0 | 100.0 | 70.7 |
| 08-29 02:00 | 2 | 2 | 0 | 100.0 | 0.5 |
| 08-29 02:10 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 02:20 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 02:30 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 02:40 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 02:50 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 03:00 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 03:10 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 03:20 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 03:30 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 03:40 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 03:50 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 04:00 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 04:10 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 04:20 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 04:30 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 04:40 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 04:50 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 05:00 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 05:10 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 05:20 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 05:30 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 05:40 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 05:50 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 06:00 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 06:10 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 06:20 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 06:30 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 06:40 | 1 | 1 | 0 | 100.0 | 0.3 |
| 08-29 06:50 | 269 | 269 | 0 | 100.0 | 73.1 |
| 08-29 07:00 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-29 07:10 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-29 07:20 | 269 | 269 | 0 | 100.0 | 73.1 |
| 08-29 07:30 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-29 07:40 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-29 07:50 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-29 08:00 | 262 | 262 | 0 | 100.0 | 71.2 |
| 08-29 08:10 | 264 | 264 | 0 | 100.0 | 71.7 |
| 08-29 08:20 | 215 | 215 | 0 | 100.0 | 58.4 |
| 08-29 08:30 | 215 | 215 | 0 | 100.0 | 58.4 |
| 08-29 08:40 | 211 | 211 | 0 | 100.0 | 57.3 |
| 08-29 08:50 | 354 | 13 | 341 | 3.7 | 3.5 |
| 08-29 09:00 | 359 | 0 | 359 | 0.0 | 0.0 |
| 08-29 09:10 | 361 | 0 | 361 | 0.0 | 0.0 |
| 08-29 09:20 | 361 | 0 | 361 | 0.0 | 0.0 |
| 08-29 09:30 | 361 | 0 | 361 | 0.0 | 0.0 |
| 08-29 09:40 | 361 | 0 | 361 | 0.0 | 0.0 |
| 08-29 09:50 | 361 | 0 | 361 | 0.0 | 0.0 |
| 08-29 10:00 | 361 | 0 | 361 | 0.0 | 0.0 |
| 08-29 10:10 | 362 | 0 | 362 | 0.0 | 0.0 |
| 08-29 10:20 | 362 | 0 | 362 | 0.0 | 0.0 |
| 08-29 10:30 | 362 | 0 | 362 | 0.0 | 0.0 |
| 08-29 10:40 | 362 | 0 | 362 | 0.0 | 0.0 |
| 08-29 10:50 | 362 | 0 | 362 | 0.0 | 0.0 |
| 08-29 11:00 | 362 | 0 | 362 | 0.0 | 0.0 |
| 08-29 11:10 | 362 | 0 | 362 | 0.0 | 0.0 |
| 08-29 11:20 | 362 | 0 | 362 | 0.0 | 0.0 |
| 08-29 11:30 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 11:40 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 11:50 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 12:00 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 12:10 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 12:20 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 12:30 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 12:40 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 12:50 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 13:00 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 13:10 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 13:20 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 13:30 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 13:40 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 13:50 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 14:00 | 363 | 0 | 363 | 0.0 | 0.0 |
| 08-29 14:10 | 50 | 0 | 50 | 0.0 | 0.0 |
| 08-29 14:20 | 11 | 0 | 11 | 0.0 | 0.0 |
| 08-29 14:30 | 1 | 0 | 1 | 0.0 | 0.0 |
| 08-29 14:40 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 14:50 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 15:00 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 15:10 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 15:20 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 15:30 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 15:40 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 15:50 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 16:00 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 16:10 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 16:20 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 16:30 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 16:40 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 16:50 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 17:00 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 17:10 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 17:20 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 17:30 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 17:40 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 17:50 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 18:00 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 18:10 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 18:20 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 18:30 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 18:40 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 18:50 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 19:00 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 19:10 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 19:20 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 19:30 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 19:40 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 19:50 | 0 | 0 | 0 | 0.0 | 0.0 |
| 08-29 20:00 | 270 | 270 | 0 | 100.0 | 73.4 |
| 08-29 20:10 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-29 20:20 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-29 20:30 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-29 20:40 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-29 20:50 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-29 21:00 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-29 21:10 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-29 21:20 | 10 | 10 | 0 | 100.0 | 2.7 |
| 08-29 21:30 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-29 21:40 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-29 21:50 | 264 | 264 | 0 | 100.0 | 71.7 |
| 08-29 22:00 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-29 22:10 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-29 22:20 | 270 | 270 | 0 | 100.0 | 73.4 |
| 08-29 22:30 | 270 | 270 | 0 | 100.0 | 73.4 |
| 08-29 22:40 | 28 | 28 | 0 | 100.0 | 7.6 |
| 08-29 22:50 | 270 | 270 | 0 | 100.0 | 73.4 |
| 08-29 23:00 | 270 | 270 | 0 | 100.0 | 73.4 |
| 08-29 23:10 | 268 | 268 | 0 | 100.0 | 72.8 |
| 08-29 23:20 | 269 | 269 | 0 | 100.0 | 73.1 |
| 08-29 23:30 | 269 | 269 | 0 | 100.0 | 73.1 |
| 08-29 23:40 | 269 | 269 | 0 | 100.0 | 73.1 |
| 08-29 23:50 | 32 | 32 | 0 | 100.0 | 8.7 |
| 08-30 00:00 | 268 | 268 | 0 | 100.0 | 72.8 |
| 08-30 00:10 | 268 | 268 | 0 | 100.0 | 72.8 |
| 08-30 00:20 | 269 | 269 | 0 | 100.0 | 73.1 |
| 08-30 00:30 | 269 | 269 | 0 | 100.0 | 73.1 |
| 08-30 00:40 | 269 | 269 | 0 | 100.0 | 73.1 |
| 08-30 00:50 | 22 | 22 | 0 | 100.0 | 6.0 |
| 08-30 01:00 | 268 | 268 | 0 | 100.0 | 72.8 |
| 08-30 01:10 | 22 | 22 | 0 | 100.0 | 6.0 |
| 08-30 01:20 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-30 01:30 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-30 01:40 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-30 01:50 | 264 | 264 | 0 | 100.0 | 71.7 |
| 08-30 02:00 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-30 02:10 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-30 02:20 | 265 | 265 | 0 | 100.0 | 72.0 |
| 08-30 02:30 | 171 | 171 | 0 | 100.0 | 46.5 |
| 08-30 02:40 | 241 | 241 | 0 | 100.0 | 65.5 |
| 08-30 02:50 | 263 | 263 | 0 | 100.0 | 71.5 |
| 08-30 03:00 | 263 | 263 | 0 | 100.0 | 71.5 |
| 08-30 03:10 | 262 | 262 | 0 | 100.0 | 71.2 |
| 08-30 03:20 | 261 | 261 | 0 | 100.0 | 70.9 |
| 08-30 03:30 | 255 | 255 | 0 | 100.0 | 69.3 |
| 08-30 03:40 | 46 | 46 | 0 | 100.0 | 12.5 |
| 08-30 03:50 | 256 | 256 | 0 | 100.0 | 69.6 |
| 08-30 04:00 | 216 | 216 | 0 | 100.0 | 58.7 |
| 08-30 04:10 | 256 | 256 | 0 | 100.0 | 69.6 |
| 08-30 04:20 | 256 | 256 | 0 | 100.0 | 69.6 |
| 08-30 04:30 | 262 | 262 | 0 | 100.0 | 71.2 |
| 08-30 04:40 | 266 | 266 | 0 | 100.0 | 72.3 |
| 08-30 04:50 | 269 | 269 | 0 | 100.0 | 73.1 |
| 08-30 05:00 | 271 | 271 | 0 | 100.0 | 73.6 |
| 08-30 05:10 | 230 | 230 | 0 | 100.0 | 62.5 |
| 08-30 05:20 | 145 | 145 | 0 | 100.0 | 39.4 |
| 08-30 05:30 | 267 | 267 | 0 | 100.0 | 72.6 |
| 08-30 05:40 | 262 | 262 | 0 | 100.0 | 71.2 |
| 08-30 05:50 | 349 | 1 | 348 | 0.3 | 0.3 |
| 08-30 06:00 | 349 | 1 | 348 | 0.3 | 0.3 |
| 08-30 06:10 | 349 | 0 | 349 | 0.0 | 0.0 |
| 08-30 06:20 | 349 | 0 | 349 | 0.0 | 0.0 |
| 08-30 06:30 | 349 | 0 | 349 | 0.0 | 0.0 |
| 08-30 06:40 | 349 | 0 | 349 | 0.0 | 0.0 |
| 08-30 06:50 | 350 | 0 | 350 | 0.0 | 0.0 |
| 08-30 07:00 | 350 | 0 | 350 | 0.0 | 0.0 |
| 08-30 07:10 | 350 | 0 | 350 | 0.0 | 0.0 |
| 08-30 07:20 | 349 | 0 | 349 | 0.0 | 0.0 |
| 08-30 07:30 | 350 | 0 | 350 | 0.0 | 0.0 |
| 08-30 07:40 | 350 | 0 | 350 | 0.0 | 0.0 |
| 08-30 07:50 | 350 | 0 | 350 | 0.0 | 0.0 |
| 08-30 08:00 | 349 | 0 | 349 | 0.0 | 0.0 |
| 08-30 08:10 | 349 | 0 | 349 | 0.0 | 0.0 |
| 08-30 08:20 | 350 | 0 | 350 | 0.0 | 0.0 |
| 08-30 08:30 | 350 | 0 | 350 | 0.0 | 0.0 |
| 08-30 08:40 | 350 | 0 | 350 | 0.0 | 0.0 |
| 08-30 08:50 | 350 | 0 | 350 | 0.0 | 0.0 |
| 08-30 09:00 | 350 | 0 | 350 | 0.0 | 0.0 |
Hetzner did not proactively notify us of the hijack. Their effective
mitigation — announcing the /24 directly — took effect at approximately 08:50 UTC on
29 August, about 12 hours after onset, and only after we contacted them on 31st August did they acknowledge the same.
Impact
Software updates — the malicious Virtualizor package
During the incident window, a Virtualizor installation whose traffic was diverted could have
received a malicious update package from the attacker’s server. Our product update clients
did not yet cryptographically verify update packages, so a modified package would not have been rejected on that basis. We believe only a small number of servers were actually affected, but we cannot produce a definitive list, so please treat every Virtualizor server as in scope for
the checks below.
Known indicator of compromise: a systemd unit at /etc/systemd/system/java-jre-update.service
(and a corresponding enabled or running java-jre-update service).
If you run Virtualizor — do this now
- Check for the indicator of compromise. Look for
/etc/systemd/system/java-jre-update.service. If it is present, your server was affected —
do not simply delete it; contact us . - Rotate and restrict Virtualizor API credentials. In the Virtualizor master (admin) panel,
reset all API keys, restrict API access to trusted IP addresses, and remove any API key you
do not recognize. - Audit access. Review the server for unknown SSH keys, new user accounts, unexpected
scheduled tasks or cron jobs, and unexpected outbound connections. Restrict SSH to trusted IP addresses. - You can also run a small cleaning script we have made :
https://files.virtualizor.com/security/virtualizor_security_scan.sh - If you find signs of compromise, contact support before remediating so we can help
preserve evidence.
Other products (Webuzo, Softaculous, Backuply, SitePad, etc.)
We have not identified a malicious package for these products. As a precaution, if one of
these servers performed an update check during the incident window, verify the server for anything suspicious and contact us if you find anything suspicious.
Billing and client area
If you logged into softaculous.com/clients or entered payment details between 28 August
~20:57 UTC and 30 August ~06:10 UTC, your session may have been diverted to the attacker’s
server.
- Reset your client-area password now. If you reused that password anywhere else, change it
there too. - Review recent account activity, and if you entered card details during the window, review
your card statements. We dont process cards from our servers and its all processed at payment gateways.
On our side, we are invalidating client-area sessions from the affected period.
License and API keys
As a precaution, regenerate your API keys from https://www.softaculous.com/clients
and update them on your servers.
Appendix A — certificate names
The fraudulently obtained certificate covered the following names:
a.softaculous.com, ampps.com, api.sitepad.com, api.softaculous.com,
api.virtualizor.com, api.webuzo.com, backuply.com, files.ampps.com, files.sitepad.com,
files.softaculous.com, files.virtualizor.com, files.webuzo.com, pagelayer.com,
popularfx.com, server.softaculous.com, sitepad.com, softaculous.com, virtualizor.com,
webuzo.com, www.ampps.com, www.backuply.com, www.popularfx.com, www.sitepad.com,
www.softaculous.com, www.virtualizor.com, www.webuzo.com.
Appendix B — methodology and data
- Prefix:
162.55.80.0/24(Hetzner; normally covered only by162.55.0.0/16).
softaculous.comresolved to162.55.80.8during the incident; the impostor host at that
address carried the reverse DNS nameserver.softaculous.com. - Hijack path: origin AS24940 (spoofed / kept on the path tail), next hop AS62390 (NexonHost),
transit AS6204 (Zet.net). First unauthorized announcement observed at2026-08-28T20:57:30Z,
example AS path20912 6204 62390 24940. - Data sources: RIPE Stat
bgp-state(10-minute snapshots), RIPE Statbgp-updatesand
RIPE Stat / RIPE RISbgplay(event stream, ~41,000 events, ~10,600 of them withdrawals),
RIPE BGPlay visualisation (https://stat.ripe.net/bgplay/162.55.80.0%2F24). - RIS peer set: 368 collector peers. All 368 carried the hijacked route at some point during
the incident. - Reliability:
bgp-statereconstructs from 8-hourly RIB dumps plus intervening updates.
Snapshots aligned to 00:00 / 08:00 / 16:00 UTC are the most accurate; between-dump values can under-count visible peers during heavy flapping. Percentages are of the RIS peer sample and approximate the share of internet networks affected; they are not a measure of traffic volume.
