
A BGP hijack against Virtualizor's update infrastructure pushed a malicious package onto VPS hypervisors running the panel, handing attackers root on every node that installed it. Hosting provider DreamIT raised the alarm on LowEndTalk shortly after midnight on 31 August, and Virtualizor confirmed it later that day.
There is no CVE for this one, and Virtualizor says the fault was not in its code. Between 28 August, around 20:57 UTC, and 30 August, around 06:10 UTC, a Hetzner range used by its services, 162.55.80.0/24, was announced by AS62390 (NexonHost) via transit AS6204 (Zet.net). The attacker held a valid TLS certificate for the hijacked domains, so servers checking for updates saw no warning and fetched a package that never came from Virtualizor. RIPE data shows the hijack ran in two waves.
What malicious update was installed
Compromised nodes carried the injected @exec() calls inside three legitimate Virtualizor files: _universal.php, globals.php and the zzvirtservice startup script. Virtualizor's own root cron job, virt_check.php, then executed them. The payload wrote an attacker's SSH key to /root/.ssh/authorized_keys, installed Java 17, downloaded widdow.jar from cdn.nerat.cc, ran it as root, and registered a systemd unit named java-jre-update.service for persistence.
Provider AlbaHost, which published the fullest forensic account, found the pattern on 5 of its 34 hypervisors. On one node, the attacker also created a proxyuser account, opened a firewall rule, and held an interactive SSH session for over three hours. Another operator traced the payload to a commodity remote-access trojan sold through ne-rat.xyz, so the intruder likely rented the tooling.
Indicators of compromise
| Type | Indicator |
|---|---|
| Systemd unit | java-jre-update.service |
| Payload | /usr/lib/jvm/.cache/jre-runtime.dat (~13.5 MB) |
| SHA-256 | b81a4e1fab9fc4e404d57224fe71e2c143aa93942bd46998789bdc944a7870c7 |
| Download | https://cdn.nerat.cc/installer/widdow.jar |
| C2 | 31.77.220.138:2025 (via connect.ne-rat.xyz) |
| SSH key fingerprint | SHA256:YQmy1hKF1h5cdJLxlZ5EScNoxe/UDWahjsWuQw2ERi8 |
| Rogue account | proxyuser, logged in from 193.32.127.248 |
| Markers | /usr/lib/jvm/.cache/.installed, /tmp/.vz_svc_done |
Which Virtualizor version is affected?
The rogue update announced itself as 3.2.9.8, but affected installs still reported 3.2.9.7 afterward. The version number proves nothing here. Check the files instead:
grep -RsnE 'cdn\.nerat\.cc|widdow\.jar|jre-runtime\.dat' /usr/local/virtualizor /etc/systemd/system /root/.ssh 2>/dev/null
systemctl status java-jre-update.service --no-pager
getent passwd proxyuser
What should operators do now?
Do not restart Virtualizor or zzvirtservice before inspecting the files, because an infected startup script will run the payload again. Virtualizor asks operators to reset all API keys, restrict API access by IP, and remove unrecognized SSH keys, and says "treat every Virtualizor server as in scope." Since the code ran as root, deletion is not remediation — a clean rebuild is. Anyone who signed in softaculous.com/clients during the window should reset that password; Virtualizor says the login page was attacker-controlled, but no database was taken.
The cPanel flaw was patched four days earlier
Control panels have had a rough week. On 27 August, cPanel patched CVE-2026-65643, a critical flaw in its domain parking and addon domain functionality. Any authenticated account allowed to add a parked domain could write arbitrary files on the server and reach code execution as root — an entire shared server lost to one cheap hosting account. Fixed builds are 11.110.0.141, 11.134.0.53, 11.136.0.37, 11.138.0.2, and 11.138.1.7 for WP Squared. cPanel did not assign a CVSS score to it.