If a website unexpectedly redirects you, sends spam emails, displays unknown files, or your browser warns you that it is dangerous, it has probably been hacked. We recommend two free tools for scanning your server for infected files:
- ClamAV: a general-purpose, open-source antivirus program that detects a wide range of malware;
- Linux Malware Detect (Maldet): specialises specifically in PHP malware (webshells, injected code) typically found on web hosting servers, and can also utilise ClamAV for scanning.
This article is intended for those operating their own VPS or dedicated server. You cannot install such programs on shared hosting; if you suspect an infection there, please contact our support team.
ClamAV
Installation
AlmaLinux, Rocky Linux (from the EPEL repository):
sudo dnf install epel-release
sudo dnf install clamav clamav-update
On AlmaLinux 10, the command clamav-update installs the clamav-freshclam package, which provides the freshclam command; the command works in exactly the same way. We tested these steps on an AlmaLinux 10.2 system, using ClamAV version 1.4.6 and Maldet version 1.6.6.
Ubuntu, Debian:
sudo apt install clamav clamav-freshclam
Updating the virus database
sudo freshclam
On Ubuntu and Debian, the clamav-freshclam service updates automatically in the background; if the log file is locked according to the freshclam command, the service is currently running and no action is required. On AlmaLinux, you can enable automatic updates using the command sudo systemctl enable --now clamav-freshclam.
Investigation
sudo clamscan -r -i /var/www
-r: also searches subdirectories,-i: lists only the infected files.
The Infected files summary line displayed at the end shows the number of matches. During the test, the EICAR test file (a harmless standard sample used to test antivirus software) placed in the /var/www directory was detected: Infected files: 1. You can also save the result to a file using the --log=/root/clamscan.log switch.
At the start of the scan, ClamAV loads the entire virus database (3.6 million signatures in this test) into memory: in this test, memory usage peaked at approximately 965 MB, and scanning a single file took nearly 3 minutes, almost entirely due to the loading process. On a 2 GB VPS without swap, this can trigger the OOM killer (see: Out of memory: OOM killer and swap file), so scan all affected directories in a single pass, rather than making numerous separate clamscan calls.
Linux Malware Detect (Maldet)
Installation
Maldet is not available in the package repositories; it must be downloaded from the developer’s (R-fx Networks) website:
cd /usr/local/src
sudo curl -LO https://www.rfxn.com/downloads/maldetect-current.tar.gz
sudo tar -xzf maldetect-current.tar.gz
cd maldetect-*/
sudo ./install.sh
(wget is not installed on the AlmaLinux cloud image, so the example uses curl.) The installer also sets up a daily check (/etc/cron.daily/maldet) and automatic signature updates.
On AlmaLinux and Rocky Linux, the sudo maldet command returns a ‘command not found’ error because Maldet is installed in the /usr/local/sbin directory, which is not included in the path used by sudo (secure_path). Specify the full path (sudo /usr/local/sbin/maldet …) or open a root shell (sudo -i). The examples below assume the latter. The settings are located in the /usr/local/maldetect/conf.maldet file.
If ClamAV is also installed, Maldet uses the clamscan engine for scanning (as indicated by the line scan_clamscan="1" in the conf.maldet file; this was the default value in the test), but with its own signatures tailored to PHP malware typically found on web hosting servers. Therefore, the two tools are not interchangeable: in the test, ClamAV detected the EICAR test file, whilst Maldet did not (malware hits 0). It is advisable to scan with both.
Investigation
# Az aláírások frissítése
maldet -u
# Egy könyvtár átvizsgálása
maldet -a /var/www
# Csak az utóbbi 7 napban módosult fájlok vizsgálata (gyorsabb)
maldet -r /var/www 7
At the end of the test, Maldet displays the summary and the report ID; for example, in the test:
maldet(17656): {scan} scan completed on /var/www: files 110, malware hits 0, cleaned hits 0, time 174s
maldet(17656): {scan} scan report saved, to view run: maldet --report 261028-2314.17656
The result:
# A vizsgálatok listája
maldet --report list
# Egy vizsgálat részletes jelentése
maldet --report SCANID
Placing detected files in quarantine (the files are then moved to the /usr/local/maldetect/quarantine directory, and the website cannot access them):
maldet -q SCANID
If a file has been placed in quarantine by mistake, you can restore it using the command maldet -s /usr/local/maldetect/quarantine/<fájlnév>. (We have not tested the quarantine and restoration processes in the absence of a genuine malware sample.)
What should you do if you find a virus?
Simply deleting the infected files is not enough: if the vulnerability exploited by the attacker remains, the website will be hacked again shortly. Recommended steps:
- Take a backup of the current state (including the infected files) for investigation purposes to a location outside the website directory.
- Identify the method of intrusion. In the web server access log (see: Reading log files on Linux), look for requests directed at the compromised files and the time they first appeared. Common causes include an out-of-date plugin, template or CMS version, or a compromised password.
- Restore the website from a clean backup, if you have one from before the infection; this is more reliable than repairing the infected files one by one.
- Update everything: the CMS, plugins and themes, as well as your server packages (see: System updates using dnf and apt). Remove any unused plugins and cracked (nulled) themes (see: Why you shouldn’t use cracked (nulled) WordPress themes and plugins?).
- Change all your passwords: those for your CMS admin accounts, your database, and your FTP/SFTP and SSH accounts.
- Also check the server: unknown users (
/etc/passwd), SSH keys (~/.ssh/authorized_keys), cron jobs (crontab -l,/etc/cron.d/) and running processes (ps aux). If the attacker has gained root access, reinstalling the server is the safest solution.
You can read about protecting WordPress sites in the article ‘Essential WordPress security settings to prevent hacking’.