This article is part of the WordPress Forensics series — practical guides for WordPress security, recovery, and migration.

Introduction

Security scanners catch the obvious malware. But sophisticated attackers know what scanners look for, and they design their code to evade detection. This guide teaches you manual forensics techniques — how to find what the automated tools miss.

Why Scanners Fail

  • Signature-based detection — Only finds known malware patterns
  • Obfuscation — Attackers encode malicious code to avoid signatures
  • Legitimate-looking code — Malware hidden in normal functions
  • Database infections — Many scanners only check files
  • Time-delayed execution — Code that only runs under certain conditions

Setting Up Your Forensics Environment

Tools You Need

  • SSH access to the server
  • Text editor with regex support (VS Code, Sublime)
  • phpMyAdmin or command-line MySQL access
  • Clean WordPress installation for comparison
  • File integrity monitoring data (if available)

Create a Forensics Snapshot

  1. Download complete site files to local machine
  2. Export full database
  3. Record current file timestamps
  4. Note server access logs location

File-Based Malware Hunting

Suspicious File Patterns

Search for these in your wp-content directory:

  • PHP files in uploads directory
  • Files with random names (abc123.php, x.php)
  • Files with recent modification dates you did not make
  • Hidden files (.file.php)
  • Files with multiple extensions (image.jpg.php)

Malicious Code Signatures

Search file contents for:

  • eval( combined with base64_decode
  • preg_replace with /e modifier
  • assert( with string parameter
  • create_function(
  • call_user_func( with dynamic function name
  • $_GET, $_POST, $_REQUEST passed to eval/system
  • shell_exec, passthru, system, exec
  • file_put_contents with user input
  • Heavily encoded strings (gzinflate, str_rot13, base64)

Finding Hidden Backdoors

Common backdoor locations:

  • wp-includes/class-wp-*.php (fake core files)
  • wp-content/themes/theme-name/functions.php
  • wp-content/plugins/plugin-name/plugin-name.php
  • wp-config.php (injected at top or bottom)
  • .htaccess (rewrite rules to malicious scripts)
  • index.php files in various directories

Database Malware Hunting

Check wp_options

SELECT option_name, option_value FROM wp_options 
WHERE option_value LIKE '%eval%' 
   OR option_value LIKE '%base64%'
   OR option_value LIKE '%script%';

Check Post Content

SELECT ID, post_title FROM wp_posts 
WHERE post_content LIKE '%<script%'
   OR post_content LIKE '%javascript:%'
   OR post_content LIKE '%onclick=%';

Check User Meta

SELECT * FROM wp_usermeta 
WHERE meta_value LIKE '%eval%' 
   OR meta_value LIKE '%base64%';

Rogue Admin Accounts

SELECT u.ID, u.user_login, u.user_email, u.user_registered 
FROM wp_users u 
JOIN wp_usermeta m ON u.ID = m.user_id 
WHERE m.meta_key = 'wp_capabilities' 
  AND m.meta_value LIKE '%administrator%';

Log Analysis

Access Log Patterns

Look for:

  • POST requests to unusual PHP files
  • Requests with base64 encoded parameters
  • Multiple failed login attempts
  • Requests to wp-includes or wp-admin from unusual IPs
  • User-agent strings with SQL injection attempts

Error Log Analysis

PHP errors often reveal malware:

  • Syntax errors in files you did not modify
  • Failed require/include of non-existent files
  • Permission denied errors from unusual locations

Core File Integrity

Compare Against Clean Installation

  1. Download fresh WordPress of same version
  2. Compare wp-includes and wp-admin directories
  3. Any modified or additional files are suspicious

WordPress Checksums

wp core verify-checksums

This WP-CLI command compares your core files against official checksums.

Timeline Analysis

  1. Identify when infection likely occurred (file timestamps, logs)
  2. Correlate with any changes made (plugin installs, theme changes)
  3. Check if backups from before that date exist
  4. Review what access was granted during that period

Documentation

For every finding, document:

  • File path or database location
  • Malicious code snippet
  • When it was likely added
  • What it does (if you can determine)
  • How it was likely injected

Conclusion

Manual forensics is time-consuming but necessary. Scanners are a starting point, not the final word. Learn to think like an attacker — where would you hide malicious code if you wanted it to survive a scanner? That is where you will find what the tools missed.