De-obfuscating Malicious PHP Code Found on a Compromised Web Server
Attackers who compromise PHP-based web servers commonly plant obfuscated scripts using eval(), preg_replace() with the /e modifier, base64_decode(), hex encoding, and XOR techniques to conceal malicious payloads such as webshells, spam mailers, and backdoors. Resolution requires isolating the server, identifying all suspect files, systematically decoding each obfuscation layer using tools such as UnPHP, PHP Beautifier, and CLI decoders to understand the payload, then cleaning, recredentialling, and hardening the environment. After confirming file integrity and patching the exploited vulnerability, the server can be safely returned to production.
Indicators
- Unknown PHP files present on the server that were not placed there intentionally
- Existing PHP files contain eval() or preg_replace() calls not present in the original source
- PHP files contain long Base64-encoded strings (e.g., strings ending in '==')
- PHP files contain hex-encoded sequences such as \x48\x65\x6c\x6c\x6f
- PHP files contain Unicode escape sequences such as \u004D\u0065
- Single-line PHP files that are thousands of characters wide with no whitespace
- Unexpected outbound traffic or spam originating from the web server
Likely causes
- Exploitation of a vulnerable CMS plugin or theme (e.g., WordPress, Joomla, Drupal)
- Weak or reused FTP/SFTP/SSH credentials brute-forced by attackers
- Use of preg_replace() with the /e modifier enabling arbitrary code execution
- File upload vulnerabilities allowing attackers to upload PHP webshells
- Outdated PHP version or web application with known unpatched vulnerabilities
- Compromised third-party library or supply-chain dependency
Diagnostic steps
-
Isolate the server or affected virtual host immediately — take it offline or block inbound/outbound web traffic at the firewall to stop active exploitation before investigating.
-
Identify all recently modified or created PHP files: run 'find /var/www -name "*.php" -newer /var/www/index.php -ls' (adjust path and reference file as appropriate) to build a list of suspect files. Note the modification timestamps for log correlation.
-
Grep for common malicious function calls across all PHP files: run 'grep -rl "eval(" /var/www', 'grep -rl "preg_replace" /var/www', and 'grep -rl "base64_decode" /var/www' to locate all affected files.
-
Copy each suspicious PHP file's contents and paste into UnPHP (archived: https://web.archive.org/web/*/https://www.unphp.net/) to attempt automated recursive de-obfuscation. Review the decoded output for the plaintext payload.
-
If the file is a single long minified line, paste it into PHP Beautifier (https://phpbeautifier.com/) to reformat it with proper indentation before attempting manual layer-by-layer analysis.
-
If Base64-encoded strings are present, extract the string passed to base64_decode() and decode it using 'echo "<base64string>" | base64 -d' in a terminal, or use a trusted offline Base64 decoder tool.
-
If hex-encoded sequences (\xNN format) are present, use a hex-to-ASCII converter or confirm the decoded value safely by wrapping the string in an echo statement in PHP Sandbox: 'echo "\x48\x65\x6c\x6c\x6f";'.
-
For XOR-obfuscated strings (common in preg_replace-based payloads), replace the eval() call with echo() in a PHP Sandbox environment (https://sandbox.onlinephpfunctions.com/) to safely print the decoded payload without executing it.
-
After revealing the final payload, document what the script does (webshell, spam mailer, backdoor, crypto miner, etc.) and review server access logs (access_log, error_log) around the file's modification timestamp to identify the initial attack vector.
Resolution path
- Take the server offline or isolate the affected virtual host at the firewall to stop active exploitation while the investigation proceeds
- Preserve forensic evidence before making changes — snapshot the disk or copy all logs and suspect files to a secure location
- Identify all malicious or modified PHP files using find and grep targeting eval(), preg_replace(), and base64_decode() patterns
- De-obfuscate each malicious file using UnPHP, PHP Beautifier, PHP Sandbox, and Base64/hex CLI decoders to fully understand the payload type and capability
- Review server access logs and error logs around the file modification timestamps to determine the initial attack vector (upload vulnerability, brute-forced credentials, exploited plugin, etc.)
- Remove all malicious files and restore legitimate files from a known-good backup or version-control repository — do not trust any file modified after the estimated compromise date
- Rotate all credentials: SSH keys and passwords, FTP/SFTP accounts, database passwords, CMS admin accounts, and any API keys stored on the server
- Update the CMS core, all plugins, all themes, and the PHP runtime itself to the latest stable patched versions before returning to production
- Implement file integrity monitoring and WAF rules, then restore the server to production only after verifying the integrity of all files against a clean baseline
Prevention
- Keep CMS core, plugins, themes, and the PHP runtime updated continuously to patch known vulnerabilities before they are exploited
- Use strong, unique passwords and SSH key-based authentication for all server access methods (SSH, FTP, SFTP, database, CMS admin)
- Disable dangerous PHP functions where not required by adding them to disable_functions in php.ini (e.g., disable_functions = exec,passthru,shell_exec,system,proc_open,popen)
- Disable the preg_replace() /e modifier at the application level; upgrade to preg_replace_callback() in custom code
- Deploy a Web Application Firewall (WAF) — such as ModSecurity with the OWASP Core Rule Set — to block common exploit patterns including file upload abuse and command injection
- Restrict file write permissions on the web root so the web server process account cannot create or modify PHP files at runtime
- Implement file integrity monitoring (e.g., AIDE, Tripwire, or a hosting-provider equivalent) to alert on unexpected creation or modification of PHP files
- Store all web application code in version control (e.g., Git) to enable rapid detection and rollback of unauthorised changes
- Regularly audit server access logs and configure alerting for anomalous outbound traffic volumes, unusual error spike patterns, and new file creation events in the web root
Tools
- UnPHP (archived: https://web.archive.org/web/*/https://www.unphp.net/) — recursive PHP de-obfuscator
- PHP Beautifier (https://phpbeautifier.com/) — reformats minified single-line PHP for readability
- PHP Sandbox (https://sandbox.onlinephpfunctions.com/) — safely run echo statements to decode strings without execution
- Base64 CLI decoder: 'echo "<string>" | base64 -d' (Linux/macOS terminal)
- find + grep (Linux CLI) — locate recently modified or suspiciously patterned PHP files
- Offline Base64Decode.exe (Windows) — for air-gapped decoding without relying on online tools
- OWASP PHP Security Cheat Sheet — reference for secure PHP configuration practices