Tutorial · Malware Detection

How to detect malware
on a Linux server

A comprehensive, step-by-step guide to finding malware on Linux servers. Manual investigation techniques, automated scanning tools, and continuous monitoring strategies.

Signs your Linux server may be infected

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.

Common indicators of compromise (IOCs)
Unexplained CPU spikes — cryptominers consume 100% CPU across all cores. Check with top or htop — if a process you don't recognize is using significant resources, investigate immediately.
Unknown processes in /tmp or /dev/shm — legitimate software never runs from world-writable temporary directories. Any executable in /tmp, /dev/shm, or /var/tmp is suspicious by default.
Unexpected outbound network connections — malware phones home to C2 servers, mining pools, or exfiltration endpoints. Outbound connections to unknown IPs on non-standard ports are a strong indicator.
Modified system binaries — rootkits replace ps, ls, netstat, and ss with trojanized versions that hide malicious activity. Verify file integrity with dpkg -V or rpm -Va.
New SSH authorized_keys entries — attackers add their public key for persistent backdoor access that survives password changes and service restarts.
Unauthorized cron jobs — persistence mechanism that re-downloads and re-installs malware even after you clean it up. Often uses curl or wget piped to bash.
PHP files in upload directories — web shells placed in WordPress wp-content/uploads, Joomla images, or Laravel storage directories. PHP files should never be in upload folders.
Recently created hidden files — files or directories starting with a dot (.) in web roots, /tmp, or home directories that you didn't create. Common malware hiding technique.
Unexpected kernel module loads — advanced rootkits load as kernel modules (LKM rootkits). Check with lsmod and compare against known modules for your distribution.
Entries in /etc/ld.so.preload — userspace rootkit indicator. Any shared library listed here is injected into every process on the system. This file should be empty or not exist.

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.

Step 1: Investigate suspicious processes

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.

Find suspicious running processes

# 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.

Step 2: Audit cron jobs and persistence mechanisms

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 all persistence locations

# 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.

Step 3: Analyze network connections

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.

Detect suspicious network activity

# 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.

Step 4: Find recently modified and suspicious files

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.

Search for suspicious files

# 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.

Step 5: Run automated detection tools

Manual checks catch active threats, but automated tools scan deeper. Each tool has different strengths. Using multiple tools gives the best coverage.

rkhunter and chkrootkit — Rootkit detection

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 rootkit scanners

# 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 — Signature-based antivirus

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 and run ClamAV

# 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 — Pattern-based malware detection

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 and use YARA

# 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 automated approach: Defensia malware scanner

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.

Install Defensia — automated malware detection

$ curl -fsSL https://defensia.cloud/install.sh | sudo bash

What Defensia detects automatically

64,000+ hash signatures (MalwareBazaar database)
684 dynamic detection patterns (YARA-compatible)
PHP web shell detection (WSO, C99, Alfa, FilesMan, and more)
Obfuscated backdoor detection (base64, eval, gzinflate)
Cryptominer process and binary detection
Reverse shell detection (bash, Python, Perl, nc)
Rootkit indicators (ld.so.preload, hidden processes, LKM)
Suspicious executables in /tmp, /dev/shm, and /var/tmp
Modified system binary detection (dpkg -V / rpm -Va)
WordPress database scanning (injected JS, rogue admins)
SUID/SGID binary audit
Credential exposure detection (.env permissions, .git/config)
Scheduled scans at configurable intervals
Real-time monitoring of upload directories
Dashboard with expandable findings and severity ratings
One-click quarantine with audit trail

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.

Detection tools compared

Each tool has different strengths. Here's what each covers:

CapabilityManualClamAVYARADefensia
Web shell detectionPartialLimitedStrongStrong
Cryptominer detectionGoodLimitedGoodStrong
Rootkit detectionHardNoPartialYes
Obfuscated codeNoNoStrongStrong
Scheduled scansNoManualManualAutomatic
Real-time monitoringNoNoNoYes
Dashboard & alertsNoNoNoYes
Zero configurationN/ANoNoYes
WP database scanningNoNoNoYes

Preventing malware in the first place

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.

Keep all software updated

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.

Deploy a web application firewall

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.

Block brute force attacks

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.

Restrict file upload handling

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.

Use SSH keys, disable password login

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.

Enable continuous monitoring

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.

What to do when you find malware

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.

Incident response checklist
1.

Document everything first — screenshot running processes, save network connection lists, copy suspicious files for analysis before you start cleaning

2.

Isolate the server — if possible, block all outbound traffic except what you need for investigation. This prevents data exfiltration and C2 communication

3.

Kill malicious processes — use kill -9 <PID> after documenting the process details from /proc/<PID>/

4.

Remove persistence — delete unauthorized cron jobs, systemd services, SSH keys, init scripts, and /etc/ld.so.preload entries

5.

Remove malware files — delete identified web shells, binaries, and scripts. Quarantine anything you want to analyze later

6.

Verify system integrity — run dpkg -V or rpm -Va and reinstall any modified packages

7.

Change all credentials — root and user passwords, database passwords, application secrets, API keys, and SSH keys

8.

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.

Stop checking manually

Defensia scans continuously, alerts instantly, and catches threats that manual checks miss.

Create Free Account

Free for 1 server. No credit card required.

Frequently asked questions

What are the signs of malware on a Linux server?

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.

How do I scan a Linux server for malware?

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.

Can Linux servers get malware?

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.

What is the best free malware scanner for Linux?

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.

What is YARA and how does it detect malware?

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.

How often should I scan my Linux server for malware?

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.

Sources

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/

Automate malware detection

64K+ hash signatures. 684 detection patterns. Scheduled scans. Real-time dashboard.

$ curl -fsSL https://defensia.cloud/install.sh | sudo bash
Create Free Account

Free for 1 server. No credit card required.