Guide · Hacked WHM/cPanel server

A hacked WHM or cPanel server is a server incident, not a site cleanup.

One account on the server is flagged — by VirusTotal, a blacklist, an ImunifyAV alert, outbound spam, or a customer complaint. The instinct is to clean that site and move on. On a shared control-panel server that instinct is how the same server gets re-flagged next month: the mechanism usually lives outside the site, in the account home, cron, the process table, or a neighbouring account. This guide sets out what to do first, what to look at, and when a per-site cleanup is safe to start.

Symptom
One or more accounts flagged, outbound spam, unknown cron or processes, load spikes
Boundary
The account and the host — not the WordPress install
First step
Preserve evidence and contain the account before deleting anything
Risk
Server-wide reinfection, blacklisting of the shared IP, silent data theft

What is happening

The site is where the symptom appeared. The server is where the problem lives.

On a WHM/cPanel or Plesk server, each hosting account is a Linux user with a home directory, a crontab, the ability to run processes, and — unless isolation is configured carefully — a view of its neighbours. A compromised WordPress site gives an attacker code execution as that user. From there the interesting places are not in public_html at all: a hidden directory under ~/.config, a cron entry that re-downloads the payload, an SSH key in ~/.ssh/authorized_keys, a cPanel API token, or an outbound tunnel that keeps working after every file cleanup.

In the engagement documented in our incident report, Wordfence flagged 283 files on one WooCommerce shop, ImunifyAV agreed, and the database export was clean. All three were right about their own layer. The backdoor was a packed ELF binary in ~/.config/htop/defunct — outside the web root, invisible to every per-site tool, on a server hosting 261 accounts. Only a root-level filesystem review found it.

That is why the order of operations matters more than the cleanup itself. Clean the site first and you destroy timestamps, overwrite logs, and leave the mechanism in place.

Signs it is the server

Symptoms that point above the site

Several accounts flagged at once

Two or more unrelated sites on the same server showing malware, spam pages, or redirects points to shared access, a shared vulnerability, or lateral movement — not a coincidence.

Outbound spam or a blacklisted IP

The server’s IP on Spamhaus, SORBS, or a mail-provider block list means something on the host is sending, whether or not any site looks infected.

Cron entries or processes nobody recognises

Entries in a user crontab that fetch a URL, run from /tmp or /dev/shm, or invoke a file with a misleading name; processes owned by a hosting account that are not PHP-FPM or a known cron job.

Load, disk, or bandwidth anomalies

Cryptominers, proxy nodes, and scanning tools show up as sustained CPU, unexplained outbound traffic, or a full /tmp before any site symptom appears.

ImunifyAV keeps flagging the same files

Files reappearing after quarantine means a generator or a scheduled task is recreating them — the quarantine is treating output, not cause.

Reinfection after a rebuild

A site rebuilt from clean sources that is compromised again within days almost always has persistence in the account, in a neighbour, or in stolen credentials.

First response

The order that protects evidence and stops the bleeding

  1. 01

    Preserve before you touch

    Take a filesystem-level snapshot or an rsync copy of the affected account’s entire home directory (not just public_html), export the crontab, and copy /var/log/messages, secure, maillog, and the Apache/Nginx and cPanel access logs for the account. Record timestamps, owners, and hashes of anything suspicious before it is deleted or quarantined.

  2. 02

    Contain the account

    Suspend the cPanel account or put the site in maintenance mode, block outbound connections for that user in CSF or the firewall, kill processes owned by the user after recording them, and disable the user’s cron. Do not delete files yet.

  3. 03

    Treat the account user as compromised

    Rotate the cPanel password, FTP/SFTP accounts, database passwords, API tokens, and any SSH keys in the account. Check ~/.ssh/authorized_keys for keys you did not add. Assume every credential stored in the account’s wp-config.php and .env files has been read.

  4. 04

    Sweep every account home, not just the flagged one

    For each user: list hidden directories and recently modified files outside public_html, look for executables where none belong, check crontabs, and compare against a known-good baseline. On a multi-account server this is the step that decides whether the incident is over.

  5. 05

    Check the server itself

    Root and reseller WHM logins and access logs, WHM API tokens, root’s authorized_keys, systemd timers, /tmp and /dev/shm contents, listening and outbound connections, and whether CageFS, PHP handler isolation, and ImunifyAV are actually enabled and enforcing.

  6. 06

    Rebuild the application layer

    Only now rebuild WordPress core, plugins, and themes from trusted sources, clean the database, and rotate WordPress credentials — following the same discipline as any hacked-site cleanup.

  7. 07

    Close the enabling condition and verify

    Patch or remove the vulnerable component, fix the isolation gap, and re-check the server after normal traffic resumes: cron, processes, outbound connections, and file changes over the following days.

Where to look

The places per-site scanners never check

Hidden directories in the account home

~/.config, ~/.cache, ~/.local, and dot-directories with names that imitate legitimate tools. Executables or packed binaries here are the artefact class from our incident report — see the gsocket guide for the exact paths to check.

User crontabs and at jobs

Entries that curl or wget a URL, execute from /tmp, or run a script with a system-looking name every few minutes are the most common persistence on cPanel servers.

authorized_keys and API tokens

An SSH key or a cPanel/WHM API token survives every password rotation and every file cleanup unless it is explicitly removed.

Processes and outbound connections

A process owned by a hosting user that holds an outbound connection to an unfamiliar host — tunnels, miners, and proxies all look like this.

World-writable and temp locations

/tmp, /dev/shm, and any world-writable path are staging areas. Files there with execute bits or recent timestamps deserve attention.

Neighbouring accounts

If isolation is weak, the flagged account may be the victim of a neighbour, or the neighbour may already be the next victim. The sweep has to cover the server.

After the incident

The controls that make the next one visible

  • File-integrity monitoring above the web root, covering account homes and cron, not just public_html.
  • Execution restrictions on home directories and temp paths; CageFS or equivalent isolation enforced for every account.
  • Outbound (egress) monitoring or restriction, so a tunnel or miner cannot phone home unnoticed.
  • Two-factor authentication and IP restriction on WHM root and reseller logins; periodic review of API tokens and SSH keys.
  • Heuristic ELF and binary detection left enabled in the malware scanner, with alerts routed to someone who acts on them.
  • A periodic root-level review of the server, independent of per-site scans — the layer this whole guide is about.

Common questions

Common questions about hacked WHM and cPanel servers

My host says only one account is infected. Can I just clean that one?

You can clean it, but you cannot conclude the incident is over from that statement alone. Ask the host what they checked: a per-account malware scan does not cover cron, processes, hidden home-directory files, or neighbouring accounts. If you administer the server, sweep it yourself or have it reviewed at root level.

Wordfence and ImunifyAV are both clean now. Is the server clean?

They are clean about their own layers — WordPress files and the files ImunifyAV is configured to scan. Neither examines the process table, user crontabs, SSH keys, API tokens, or a packed binary in a hidden dot-directory. The documented WHM incident is exactly this case.

Should I reinstall the whole server?

Sometimes. If root access is suspected, if isolation was never configured, or if the number of accounts makes a reliable sweep impractical, a rebuild onto a fresh host with accounts restored from verified-clean application sources is the safer path. A contained single-account compromise with intact root controls usually does not need it.

Can you do this for a server I manage for clients?

Yes. Agencies and resellers are the most common case. The work is scoped as a server audit with incident handling, ownership of client communication and per-site cleanup is agreed up front, and the report separates server findings from per-account actions.