An interactive, browser-based incident response playbook for system administrators and developers to rapidly detect, eradicate, and recover from advanced WordPress server compromises. Built from a real production incident involving compiled binary malware, XOR-cipher webshells, cryptominers, SSH backdoors, and 49,000+ ghost users on a live WooCommerce store.
v2.0 is a complete rewrite β not just updated commands but an entirely new threat model based on a real multi-layered attack chain. If you used v1.0, upgrade immediately.
Most WordPress security guides assume simple PHP webshell infections. This playbook was built from a real advanced attack that involved:
- Compiled Linux ELF binaries planted inside plugin directories disguised as legitimate files β completely invisible to PHP-only scanners
- XOR-cipher PHP webshells using a consistent salt signature for detection
- Cryptominer deployment consuming 96β176% CPU per process
- SSH backdoor β unknown SSH keys planted in
authorized_keysfor persistent remote access - 49,394 ghost WordPress users registered with no role
- WooCommerce core file injection β 6 core files modified (likely for payment interception)
- Coordinated brute-force attacks on
wp-login.phpacross all sites simultaneously - Persistence mechanism β binaries recreated webshells, webshells recreated binaries
Standard security plugins cannot detect compiled binaries. Dashboard access is usually broken. Recovery must be done entirely at the server level via terminal.
| Feature | v1.0 | v2.0 |
|---|---|---|
| Binary malware detection | β | β Full no-extension executable scan |
| XOR webshell salt scanner | β | β Single grep finds all variants |
| SSH authorized_keys audit | β | β With known attacker key examples |
| Ghost user cleanup | β | β 49k+ user deletion commands |
| Brute force protection | β | β .htaccess + UFW dual-layer |
| Firewall configuration | β | β Hostinger + XCloud + UFW layered setup |
| Cloudflare hardening | β | β Full (Strict) SSL + WAF rules |
| Monarx scanner install | β | β Step-by-step with GPG key fix |
| WooCommerce order migration | β | β Safe HPOS-compatible export/import |
| Known attacker file reference | β | β Real paths from real incident |
| Post-recovery hardening tab | β | β PHP functions, file mods, cron |
| Interactive checklist | β | β 30-item verification checklist |
| Server IP fields | β | β Personal IP + server IP vars |
| Attack chain reference | β | β Full 7-stage attack documentation |
| Tabs | 2 | 4 (WP-CLI, Manual, Hardening, Checklist) |
- Clone or download this repository
- Open
index.htmlin any modern browser β no server required - Fill in the Global Server Configuration panel with your actual server paths and IPs β all commands update instantly
- Work through each phase in order β do not skip phases
git clone https://github.com/yasirshabbirservices/wp-security-malware-recovery.git
cd wp-security-malware-recovery
open index.htmlIdentify and kill malicious CPU-hogging processes. Known malware binary names from real attacks: wpbooster, reminder_actions, linkr_button, DeleteFolder. These run as the site's PHP user at 20β176% CPU each.
This is the #1 reason infections persist after cleanup. Attackers plant compiled Linux ELF executables with no file extension inside plugin/theme directories. These survive PHP-only scans, plugin reinstalls, and even WordPress core replacements. The playbook provides a comprehensive find command that scans your entire /var/www tree for executables, excluding all known legitimate file types.
The attacker's XOR-cipher webshells share a consistent salt signature (abcdefghijklmnopqrstuvwxyz0123456789). A single grep command finds every variant regardless of filename, directory, or obfuscation level. Real attacker locations documented with exact paths.
Restore WordPress core from checksums. Restore specific infected plugin files from GitHub raw URLs. Never overwrite β always delete and reinstall. Verify checksums after.
Change DB credentials, rotate WP secret keys, audit and remove ghost users, verify no unknown admin accounts.
Disable dangerous PHP functions (exec, shell_exec, system, passthru), lock WordPress file modifications, block PHP execution in uploads, deploy hourly binary scan cron job, install Monarx server scanner, configure layered firewall (Hostinger β UFW β Cloudflare).
30-item checklist covering every layer. Ongoing monitoring commands. Weekly salt scan schedule.
-
Deleting PHP webshells is not enough. If compiled binaries are still running, they recreate the webshells within minutes. Kill binaries FIRST.
-
Plugin reinstalls don't help if binaries survive. The binary malware lived INSIDE plugin directories. Reinstalling the plugin from WordPress.org over an existing directory leaves the binary in place.
-
The attacker had SSH key access. Unknown keys were found in
~/.ssh/authorized_keys. Always audit this file β it's permanent backdoor access that survives all WordPress-level cleanup. -
UFW and Hostinger firewall are separate layers. Removing ports from XCloud/UFW while Hostinger firewall had them open (or vice versa) caused a 522 error across all sites. Both layers must be configured.
-
WooCommerce now uses HPOS (
wp_wc_orderstable, notwp_posts). Standard order migration tutorials that referencewp_postswill fail silently β orders will show as 0 even when hundreds exist. -
One command at a time. Copy-pasting multiple commands causes
\rcarriage return errors that break execution without any visible error message.
| Layer | Tool | What It Does |
|---|---|---|
| Network | Cloudflare Free | DDoS, bot blocking, WAF rules |
| Server (scan) | Monarx Free | Continuous file malware detection |
| Server (monitor) | Hourly cron job | Executable binary detection |
| WordPress | Wordfence Free | Firewall + malware scan + login protection |
| Brute force | .htaccess + Fail2Ban | wp-login.php protection |
Documented from the real incident. Check these paths on any compromised server:
wp-content/plugins/wpvivid-backuprestore/vendor/guzzle/guzzle/src/Guzzle/Plugin/Cookie/CookieJar/madblanks.php
wp-content/plugins/wpvivid-backuprestore/vendor/guzzle/guzzle/src/Guzzle/Service/Command/Factory/advertiser.php
wp-content/plugins/woocommerce/packages/email-editor/vendor-prefixed/packages/Sabberworm/CSS/sp_getthumb.php
wp-content/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Settings/Email/Schema/db_tracking.php
wp-content/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Settings/Email/Schema/forgot_mail.php
wp-content/themes/bricks/includes/integrations/svg-sanitizer/library/vendor/enshrined/svg-sanitize/src/svg.php
wp-content/themes/bricks/includes/utilities/comments.php
wp-content/plugins/bricks-advanced-themer/acf-pro/includes/admin/views/upgrade/.rvsPublish.ini
wp-admin/images/reminder_actions [BINARY]
wp-content/plugins/wordpress-seo/src/ai-free-sparks/application/DeleteFolder [BINARY]
wp-content/plugins/optimole-static-advanced/wpbooster [BINARY - cryptominer]
Run these on any suspected server immediately:
# Find all compiled binaries (no file extension executables)
find /var/www -type f ! -name "*.*" -executable 2>/dev/null
# Find XOR webshells (attacker's cipher salt)
grep -rl "abcdefghijklmnopqrstuvwxyz0123456789" /var/www/*/wp-content/ --include="*.php" 2>/dev/null
# Audit SSH authorized keys
cat ~/.ssh/authorized_keys
# Check for rogue admin users
wp user list --role=administrator --allow-root
# Count ghost users (no role)
wp db query "SELECT COUNT(*) FROM wp_users u LEFT JOIN wp_usermeta m ON u.ID = m.user_id AND m.meta_key = 'wp_capabilities' WHERE m.meta_value IS NULL OR m.meta_value = 'a:0:{}';" --allow-rootYasir Shabbir β Full-Stack Web Developer & Software Engineer
- Website: yasirshabbir.com
- This playbook was built and battle-tested during a real production WooCommerce incident on a Hostinger KVM VPS running Ubuntu 24.04, OpenLiteSpeed, PHP 8.3, MySQL 8.0, managed via XCloud with Cloudflare in front.
MIT License β fork it, modify it, use it to save your servers. If it helped you, a β on GitHub goes a long way.
- Added
bulk-scan.shβ parallel multi-site scanner for entire server - Configurable
MAX_JOBSconcurrency (default 6, safe for 1000+ sites) - Auto-filters known false positives (Base64VLQ, WooCommerce vendor, razorpay SDK, etc.)
- Separate severity levels: CRITICAL π΄ / WARNING π‘ / CLEAN β
- Timestamped log files in
/var/log/wp-security-scan/ .user.iniscan withauto_prepend_filedetection (PHP config override backdoor)- Suspicious wp-admin file detection with random filename pattern matching
- New Bulk Server Scan tab in playbook UI
- False positive reference table with plugin attribution
- Added core checksum failure fix command (force-download without touching wp-content)
- Weekly automated scan cron job template
- Complete rewrite based on real advanced multi-vector attack incident
- Added binary malware detection (the missing piece in v1.0)
- Added XOR webshell salt scanner
- Added SSH authorized_keys audit
- Added ghost user detection and cleanup
- Added server hardening tab (PHP functions, file mods, cron monitoring)
- Added interactive 30-item verification checklist
- Added WooCommerce HPOS-compatible order migration guide
- Added layered firewall configuration (Hostinger + UFW + Cloudflare)
- Added Monarx scanner installation with Ubuntu Noble fix
- Added known attacker file path reference table
- Added attack chain documentation (7 stages)
- New dark terminal aesthetic with JetBrains Mono
- Initial release
- Basic WP-CLI and manual recovery commands
- Core verification and plugin reinstall
- DB password rotation