The short version: We recently caught and shut down a phishing operation that had been running out of a long-suspended hosting account on one of our shared servers. The account had been frozen for over a year — but the website attached to it was still being served, and attackers had quietly turned it into a phishing page impersonating a well-known investment platform. We took the malicious pages offline, rotated every credential, preserved the evidence, and notified the account holder.
If you've never thought about this, you're not alone. When a hosting account is "suspended," most people picture the website going dark. In practice, suspension on cPanel only locks the login surface — the website itself can keep on being served by the web server until somebody explicitly tells it to stop. That gap is exactly what an attacker needs.
A long-suspended account on one of our shared cPanel servers, originally belonging to a defunct overseas tour-operator business, had been quietly hosting a multi-stage phishing kit. The kit imitated a major brand-name investment platform's login flow and was capturing credentials from anyone who clicked through a phishing email and landed on the page. Investigation showed it had been running for months, possibly years, with hundreds of victim interactions logged.
Read the full technical breakdown ↓
What we did about it
- Took the malicious pages offline at the web-server level so they would stop responding immediately
- Rotated every credential associated with the account
- Cleaned and reset the account's auto-installer, which was being used as a hidden persistence mechanism
- Preserved a forensic archive of the entire operation
- Notified the account-of-record so the account can be permanently terminated
If you have a hosting account you stopped using a year ago, two years ago, five years ago — and you assumed it was effectively dead — it's worth a check. Suspended is not the same as stopped. If you'd like Cybersalt to take a look at your own setup, get in touch.
The technical breakdown
The rest of this post is for fellow IT and security folks who want the receipts. If you came for the summary, you're done — thanks for reading.
Discovery
The first signal came from a routine file scan on the shared server. An entry flagged a pattern matching a known phishing kit's obfuscated PHP. We pulled the file path and started walking the directory tree.
Findings
In the suspended account's public_html, the attacker had built a complete phishing operation:
- A multi-tier landing page mimicking the investment brand's login flow
- PHP collectors that wrote captured credentials and 2FA codes to flat files
- A logging directory with hundreds of victim sessions, dated over several months
Two more findings made it clear this wasn't a one-off compromise.
Persistence via the auto-installer. Softaculous (the cPanel one-click installer) keeps a per-user config file at ~/.softaculous/user.php. The attacker had modified it to register their own email as the account's contact address. Result: even if we reset the cPanel password, the attacker could trigger Softaculous's "forgot password" flow and have a reset link sent to their inbox. This is a hijack mechanism that survives a basic password reset.
Backup metadata predating the suspension. Inside the same Softaculous directory, backup snapshots from October 2020 already carried an attacker-owned email address. That means the original compromise predated the account's suspension by roughly four-and-a-half years. The "suspension" had been irrelevant to the attacker the entire time.
Apache was still serving the vhost. Despite the cPanel account being suspended for over a year, the web server's virtual-host configuration for the account's domain was still active. cPanel's suspension only locks login surfaces (cPanel UI, FTP, SSH, mail) — it does not by itself stop Apache from serving files out of the account's public_html. The attacker had been relying on this gap.
Remediation
Steps taken, in order:
1. Forensic snapshot first. Tarred up public_html and the attacker-owned mailbox directories with ACLs and extended attributes preserved (tar --acls --xattrs) and stored the archive in a quarantine location outside the account. This had to happen before anything destructive — once you start deleting files you can't get the receipts back.
2. Stopped Apache from serving the vhost. Verified the suspension's vhost-level handler was actually returning HTTP 403 on the live domain. One gotcha worth knowing: if you verify with curl, hit the real hostname, not the IP with a spoofed Host: header. The IP-direct test will return HTTP/2 421 "Misdirected Request" because Apache rejects at the SNI cert layer before it ever evaluates the suspension handler — that 421 isn't a sign that suspension is broken, just that you're testing the wrong way.
3. Rotated the cPanel password and all associated credentials. From the WHM root session, ran:
whmapi1 passwd user=<account>
That single call rotates the system, FTP, mail, MySQL, and webdisk passwords in one shot. (/usr/local/cpanel/bin/realpasswd is no longer present on current cPanel builds, so don't reach for that.)
4. Reset the registered contact email — the API lied. Tried the obvious path first:
whmapi1 modifyacct user=<account> CONTACTEMAIL=<legitimate>
…and got back result: 1, "Account Modified". Looked successful. But the cpuser file on disk was unchanged. whmapi1 modifyacct silently no-ops on suspended accounts while still returning a success status code. Worked around it with a direct edit:
sed -i 's/^CONTACTEMAIL=.*/CONTACTEMAIL=<legit>/' /var/cpanel/users/<account>
/usr/local/cpanel/scripts/updateuserdomains
/usr/local/cpanel/scripts/updateuserdatacache --force
Worth knowing if you ever need to fix metadata on a suspended account — the API will tell you it succeeded while the file on disk stays untouched.
5. Reset the Softaculous registered email. Edited ~/.softaculous/user.php to put the legitimate contact email back into the registered-email field, then verified by grepping for the attacker's address and confirming zero matches. Without this step the password reset in step 3 would be reversible by the attacker via Softaculous's password-recovery flow.
6. Cleaned third-party monitoring config. Discovered that the cPanel Koality monitoring add-on had also been signed up under one of the attacker's email addresses, and cleared the nvdata config so the next subscription couldn't be hijacked the same way. Whatever third-party services your hosting environment offers, check whether they keep their own user-config files outside of the standard cPanel ones — those are the ones an attacker can hide in.
7. Final sweep. Grepped every relevant config file — /var/cpanel/users/<account>, ~/.cpanel/contactinfo, ~/.softaculous/user.php, Koality nvdata, the cpuser .bak — for every known attacker email address. Final result: zero matches across the board.
8. Verified the kit was unreachable. curl against every URL in the phishing kit returned HTTP 403 from the suspension handler. Operation dark.
What I learned, and would do differently
Suspension is not the same as taking the site down. This is the single biggest takeaway. If you suspend a cPanel account because the customer left, the abuse stopped paying, or the account is "dead," the website attached to that account is still being served by Apache until you explicitly stop it. For any long-term suspension, also disable the vhost (or drop a deny-all .htaccess into the docroot) so nothing under that domain can be requested. We're now doing a sweep across our other shared environments to find any other suspended accounts that are still serving content.
Softaculous user-email is a real persistence vector. It's not a file most administrators think to audit. Adding it to the post-incident checklist for any compromised account: rotate the cPanel password, and check ~/.softaculous/user.php, and check whatever third-party monitoring services have nvdata config of their own (Koality and similar).
whmapi1 modifyacct lies on suspended accounts. Silent failure with a success status code is the worst class of bug. If you're updating cpuser metadata as part of an incident response, verify by reading the file on disk afterwards — don't trust the API return code.
Forensics before remediation, every time. It's tempting to start cleaning the moment you find the kit. Fight that. A five-minute tar archive at the start of the incident is worth more than a week of trying to reconstruct what happened from cPanel backups after the fact.
← Back to the plain-English summary

Add comment