A comprehensive, step-by-step guide to finding malware on Linux servers. Manual investigation techniques, automated scanning tools, and continuous monitoring strategies.
Malware on Linux servers rarely announces itself. Attackers want persistent, quiet access. The symptoms are subtle, but knowing what to look for turns a vague "something feels wrong" into actionable investigation. If you've already confirmed an infection, see our Linux malware removal guide for cleanup steps.
Even one of these indicators warrants a full investigation. The detection steps below work on Ubuntu, Debian, CentOS, Rocky Linux, AlmaLinux, and all RHEL-based distributions.
The first place to look is what's running on your server right now. Cryptominers, reverse shells, and botnets all leave process footprints. This is the fastest way to detect active malware.
# List processes sorted by CPU usage (cryptominers pin 100% on all cores)
$ ps aux --sort=-%cpu | head -20
# List processes sorted by memory usage (some malware is memory-intensive)
$ ps aux --sort=-%mem | head -20
# Find processes running from temporary or world-writable directories
$ ls -la /proc/*/exe 2>/dev/null | grep -E '(/tmp|/dev/shm|/var/tmp|/run/)'
# Find processes with deleted executables (malware self-deletes after launch)
$ ls -la /proc/*/exe 2>/dev/null | grep deleted
# Show process tree to identify parent-child relationships
$ ps auxf | grep -E '(tmp|shm|\.hidden|kworker|kthread)' | grep -v grep
# Check for processes masquerading as kernel threads (names in brackets)
$ ps aux | awk '$11 ~ /^\[/ {print}' | head -20
What to look for: Processes running from /tmp, /dev/shm, or hidden directories (/.hidden, /tmp/.X11). Legitimate software never runs from these locations. Also watch for names that mimic system processes like kworkerds, kdevtmpfsi, or [kthreadd] with the wrong PID.
If you find a suspicious process, note the PID before killing it. Run ls -la /proc/<PID>/exe to find the binary location, cat /proc/<PID>/cmdline | tr '\0' ' ' to see the full command, and ls -la /proc/<PID>/fd/ to see open file descriptors and network connections.
Malware needs to survive reboots and cleanup attempts. Cron jobs are the most common persistence mechanism on Linux servers because they're easy to install and often overlooked during investigation. For a complete hardening approach, follow our Linux server security guide.
# Check crontabs for every user on the system
$ for user in $(cut -f1 -d: /etc/passwd); do crontab -l -u $user 2>/dev/null | grep -v "^#" | grep -v "^$" && echo " ^ crontab for: $user"; done
# Check system cron directories
$ ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ 2>/dev/null
# Check /etc/crontab for unexpected entries
$ cat /etc/crontab
# Check systemd timers (modern cron replacement)
$ systemctl list-timers --all
# Check for unknown systemd services
$ systemctl list-unit-files --type=service --state=enabled | grep -v vendor
# Check rc.local and init.d for legacy persistence
$ cat /etc/rc.local 2>/dev/null
$ ls -la /etc/init.d/ | grep -v -E '(README|skeleton)'
# Check for unauthorized SSH keys (backdoor access)
$ find / -name authorized_keys -exec ls -la {} \; 2>/dev/null
$ find / -name authorized_keys -exec cat {} \; 2>/dev/null | wc -l
Red flags: Cron jobs that download scripts with curl or wget and pipe to bash. Entries in /etc/cron.d/ with random-looking filenames. Systemd services with generic names like system-update.service or network-helper.service that you didn't create.
Malware communicates. Cryptominers connect to mining pools. Reverse shells maintain outbound connections to attacker-controlled servers. Botnets receive commands from C2 (command and control) infrastructure. These connections are visible if you know where to look.
# Show all listening ports and their processes
$ sudo netstat -tulnp
# or with ss (modern replacement for netstat)
$ sudo ss -tulnp
# Show all established outbound connections
$ sudo netstat -anp | grep ESTABLISHED | grep -v '127.0.0.1' | grep -v '::1'
# Find processes with active network connections
$ sudo ss -tnp | awk '{print $5, $6}' | sort -u
# Check for connections to known mining pool ports (3333, 4444, 5555, 8888)
$ sudo ss -tnp | grep -E ':3333|:4444|:5555|:8888|:14444|:45700'
# Check DNS queries for suspicious domains (if tcpdump available)
$ sudo tcpdump -i any -n port 53 -c 100 2>/dev/null | grep -i 'A?'
# Check iptables for rules you didn't create (malware sometimes adds rules)
$ sudo iptables -L -n --line-numbers
What to investigate: Any outbound connection to an IP address you don't recognize, especially on non-standard ports. Connections to IPs in China, Russia, or Eastern Europe from servers that serve only domestic traffic. Multiple connections to the same IP on high-numbered ports. Any process listening on a port you didn't configure.
Malware leaves files on disk: web shells in web directories, binaries in /tmp, configuration changes in system paths. Finding these files is one of the most reliable detection methods.
# Find files modified in the last 7 days in web directories
$ find /var/www -type f -mtime -7 2>/dev/null | head -50
# Find PHP files in upload directories (almost always malicious)
$ find /var/www -path "*/uploads/*.php" -type f 2>/dev/null
$ find /var/www -path "*/wp-content/uploads/*.php" -type f 2>/dev/null
# Find executable files in temporary directories
$ find /tmp /dev/shm /var/tmp -type f -executable 2>/dev/null
# Find PHP files with suspicious functions (web shells)
$ grep -rl "eval(base64_decode\|passthru\|shell_exec\|system(" /var/www --include="*.php" 2>/dev/null
# Find files with suspicious names (common malware names)
$ find /var/www -name "*.php" -type f | grep -iE '(c99|r57|wso|alfa|b374k|shell|hack|cmd)' 2>/dev/null
# Find hidden files and directories in web roots
$ find /var/www -name ".*" -type f 2>/dev/null
# Check file integrity against package manager records
# Debian/Ubuntu:
$ sudo dpkg -V 2>/dev/null
# RHEL/CentOS:
$ sudo rpm -Va 2>/dev/null | grep -v "^\.\.\.\.\.\.\.\.T"
# Find SUID/SGID binaries (privilege escalation risk)
$ find / -perm -4000 -type f 2>/dev/null | sort
Pay special attention to PHP files larger than 100KB with encoded content — legitimate PHP files rarely exceed this size with base64-encoded payloads. Files with random-looking names like xk82jf.php or names that mimic system files like wp-config-backup.php are common web shell naming patterns. Also check /etc/ld.so.preload — any entry in this file means a rootkit is loading a shared library into every process on the system.
Manual checks catch active threats, but automated tools scan deeper. Each tool has different strengths. Using multiple tools gives the best coverage.
These two free tools check for the most common rootkit signatures, hidden processes, and system binary modifications. Run both — they use different detection databases and catch different threats.
# Install and run rkhunter (Debian/Ubuntu)
$ sudo apt update && sudo apt install rkhunter -y
$ sudo rkhunter --update
$ sudo rkhunter --check --sk
# Install and run chkrootkit (Debian/Ubuntu)
$ sudo apt install chkrootkit -y
$ sudo chkrootkit
# On RHEL/CentOS, install via EPEL
$ sudo dnf install epel-release -y
$ sudo dnf install rkhunter -y
$ sudo rkhunter --update && sudo rkhunter --check --sk
ClamAV is the most widely used free antivirus for Linux. It's a solid first pass for known malware hashes, but it was designed for email gateway scanning and misses many web shells and server-specific threats.
# Install ClamAV (Debian/Ubuntu)
$ sudo apt update && sudo apt install clamav clamav-daemon -y
# Update virus definitions
$ sudo systemctl stop clamav-freshclam
$ sudo freshclam
$ sudo systemctl start clamav-freshclam
# Scan web directories and common malware locations
$ sudo clamscan -ri /var/www /tmp /home /dev/shm --log=/var/log/clamav-scan.log
# View detected threats
$ grep FOUND /var/log/clamav-scan.log
ClamAV limitations: ClamAV misses many PHP web shells, obfuscated backdoors, and modern server-targeted malware. Full scans on large directories can take hours. Its signature database is community-maintained and may lag behind new threats. Use it as one tool in your toolkit, not your only scanner.
YARA is the tool professional malware analysts use. Instead of matching file hashes (which change when attackers modify one byte), YARA matches patterns: strings, byte sequences, regular expressions, and logical conditions. This makes it far more effective at catching malware variants and obfuscated code.
# Install YARA (Debian/Ubuntu)
$ sudo apt update && sudo apt install yara -y
# Install YARA (RHEL/CentOS)
$ sudo dnf install epel-release -y && sudo dnf install yara -y
# Verify installation
$ yara --version
# Example: scan a directory with a YARA rules file
$ yara -r /path/to/rules.yar /var/www/
# Example: write a simple web shell detection rule
$ cat <<'EOF' > /tmp/webshell.yar
rule PHP_WebShell {
strings:
$eval = "eval(base64_decode(" nocase
$system = "system($_" nocase
$shell = "shell_exec(" nocase
$passthru = "passthru(" nocase
condition:
any of them
}
EOF
$ yara -r /tmp/webshell.yar /var/www/
Writing effective YARA rules requires malware analysis expertise. Defensia includes 684 pre-built YARA-compatible detection patterns covering PHP web shells, cryptominers, reverse shells, backdoors, and obfuscated code — all maintained and updated automatically.
The manual steps above are thorough but time-consuming. They require expertise to interpret results, and they only detect malware at the moment you run them. Defensia automates everything — continuous detection with a single install command.
$ curl -fsSL https://defensia.cloud/install.sh | sudo bash
Defensia runs scheduled scans at configurable intervals and monitors upload directories in real time. When malware is detected, it appears instantly in the dashboard with severity ratings, file paths, matched signatures, and one-click quarantine. Alerts fire via Slack, email, Discord, or webhook.
YARA integration: If YARA is installed on your server, Defensia automatically uses it for deeper pattern matching. The agent detects YARA at startup and combines its 684 pattern rules with YARA's engine for maximum detection coverage. No configuration needed — just install YARA and restart the agent.
Each tool has different strengths. Here's what each covers:
| Capability | Manual | ClamAV | YARA | Defensia |
|---|---|---|---|---|
| Web shell detection | Partial | Limited | Strong | Strong |
| Cryptominer detection | Good | Limited | Good | Strong |
| Rootkit detection | Hard | No | Partial | Yes |
| Obfuscated code | No | No | Strong | Strong |
| Scheduled scans | No | Manual | Manual | Automatic |
| Real-time monitoring | No | No | No | Yes |
| Dashboard & alerts | No | No | No | Yes |
| Zero configuration | N/A | No | No | Yes |
| WP database scanning | No | No | No | Yes |
Detection is reactive. The best security strategy combines detection with prevention to stop malware before it reaches your server. Follow our VPS security checklist for the complete hardening process.
Run apt upgrade or dnf update regularly. Enable unattended-upgrades (Debian/Ubuntu) or dnf-automatic (RHEL). Most malware exploits known vulnerabilities with available patches — the median time between CVE disclosure and exploitation was under 5 days in 2025.
A WAF blocks the exploit attempts that lead to malware installation in the first place. SQL injection, file upload bypasses, and remote code execution attempts are caught before they reach your application. Defensia's WAF works from nginx/Apache logs with zero configuration.
SSH and web login brute force attacks are the primary entry points for server compromise. Automated blocking prevents attackers from guessing credentials. Defensia detects 15 SSH attack patterns and blocks within seconds.
Configure your web server to never execute PHP (or any script) inside upload directories. Add "php_flag engine off" in .htaccess or use location blocks in nginx to deny script execution in upload paths.
Password authentication allows brute force attacks. SSH key authentication with PasswordAuthentication no in sshd_config eliminates this attack vector entirely. See our Linux server security guide for the full SSH hardening steps.
Manual scans only catch malware at the moment you run them. Defensia provides scheduled automated scans plus real-time monitoring of upload directories — catching new malware within seconds of it appearing on disk.
If your investigation confirms malware, act methodically. Missing any persistence mechanism means the attacker returns within hours. See our detailed malware removal guide for the full cleanup procedure.
Document everything first — screenshot running processes, save network connection lists, copy suspicious files for analysis before you start cleaning
Isolate the server — if possible, block all outbound traffic except what you need for investigation. This prevents data exfiltration and C2 communication
Kill malicious processes — use kill -9 <PID> after documenting the process details from /proc/<PID>/
Remove persistence — delete unauthorized cron jobs, systemd services, SSH keys, init scripts, and /etc/ld.so.preload entries
Remove malware files — delete identified web shells, binaries, and scripts. Quarantine anything you want to analyze later
Verify system integrity — run dpkg -V or rpm -Va and reinstall any modified packages
Change all credentials — root and user passwords, database passwords, application secrets, API keys, and SSH keys
Install continuous monitoring — deploy Defensia or another monitoring tool to detect reinfection attempts immediately
If you found a rootkit: Do not trust any commands on the compromised system. Rootkits modify system binaries (ps, ls, netstat) to hide their presence. The only safe remediation is to provision a new server, restore data from a known-clean backup, and harden before reconnecting to the network.
Defensia scans continuously, alerts instantly, and catches threats that manual checks miss.
Create Free AccountFree for 1 server. No credit card required.
The most common signs are unexplained high CPU usage (cryptominers), unknown processes running from /tmp or /dev/shm, unauthorized SSH keys in authorized_keys files, unexpected cron jobs that download scripts, outbound connections to unknown IPs, recently modified PHP files in web directories, and entries in /etc/ld.so.preload. Any single indicator warrants a full investigation using the steps in this guide.
Start with manual checks: ps aux for suspicious processes, netstat -tulnp for unusual connections, and find to locate recently modified files. Then run automated tools: rkhunter and chkrootkit for rootkits, ClamAV for known signatures, and YARA for pattern-based detection. For comprehensive automated coverage, Defensia combines 64,000+ hash signatures with 684 dynamic detection patterns and runs on schedule.
Yes. Linux servers are actively targeted by cryptominers, web shells, rootkits, backdoors, and ransomware. The misconception that Linux is immune to malware is dangerous. Any server exposed to the internet receives automated attacks within minutes. Web servers running PHP (WordPress, Laravel, Joomla) are especially targeted through vulnerable plugins and file upload vulnerabilities.
ClamAV is the most widely used free scanner, but it was designed for email gateways and misses many web shells and server-specific malware. rkhunter and chkrootkit are free rootkit detectors. For the best free coverage, combine all three with manual process and network checks. Defensia offers a free tier for 1 server that includes a malware scanner with 64K+ signatures and 684 detection patterns.
YARA is a pattern-matching tool used by security researchers to identify and classify malware. Unlike hash-based detection (which fails when attackers change one byte), YARA matches patterns: strings, byte sequences, regular expressions, and logical conditions found in malicious files. This makes it effective against malware variants and obfuscated code. Defensia includes 684 pre-built YARA-compatible patterns that are maintained and updated automatically.
At minimum, run a full scan weekly and after any security incident. For production web servers handling user uploads or running CMS platforms like WordPress, daily automated scans are recommended. Real-time file monitoring is ideal — Defensia watches upload directories continuously and flags new PHP files within seconds of them appearing on disk.
Defensia malware scanner: tested on 9 production servers, 64K+ hash signatures from MalwareBazaar (2025-2026)
ClamAV documentation: https://docs.clamav.net/
rkhunter documentation: http://rkhunter.sourceforge.net/
YARA documentation: https://yara.readthedocs.io/
NIST SP 800-83: Guide to Malware Incident Prevention and Handling — https://csrc.nist.gov/publications/detail/sp/800-83/rev-1/final
MalwareBazaar (abuse.ch): https://bazaar.abuse.ch/
SANS Institute: Linux Server Incident Response — https://www.sans.org/white-papers/33901/
64K+ hash signatures. 684 detection patterns. Scheduled scans. Real-time dashboard.
Free for 1 server. No credit card required.