What WP-VCD is
WP-VCD is a long-running WordPress malware family that first appeared around 2017 and remains active in 2026. Unlike one-shot infections, WP-VCD is engineered for persistence — it has multiple redundant backdoors, replicates across plugins, and re-deploys itself if you remove only part of it.
The original infection vector was almost always a "nulled" (pirated) premium theme or plugin downloaded from sketchy sites. The pirate's distribution package contained a bonus payload. Once activated, WP-VCD spread.
This article documents how WP-VCD survives standard cleanups and the procedure that actually removes every piece.
How WP-VCD spreads inside your site
The infection has 5-7 components, each designed to restore the others if any is removed:
Component 1 — class.theme-modules.php
Located in the active theme's functions.php or as theme-modules.php in the theme root. This is the core loader. Removing only this is what most "cleanups" do — and the other components rebuild it.
Component 2 — wp-vcd.php
A small file dropped into wp-includes/ (where WordPress core lives). On every page load, WordPress's index.php includes it. Removing it means it gets re-dropped by component 3 within hours.
Component 3 — wp-tmp.php
Hidden in wp-content/themes/<active>/ or wp-content/plugins/<random>/. Acts as a re-installer — if it sees component 1 or 2 missing, it downloads fresh copies from the C2 server.
Component 4 — Modified .htaccess
Adds URL rewrite rules that route certain spam URLs to a script-generated page. This is how the search-spam payload reaches Google.
Component 5 — Backdoor user
A hidden admin user (often named 100010010, admin1, or with display_name as "100010010") that the malware uses to log in via a cookie bypass.
Component 6 — Database options
Entries in wp_options like wp_vcd_settings, wp_seo_data, with serialized configuration. Removing component 1 without removing these leaves the malware "knowing" it was installed.
Component 7 — Cross-site replication
If your hosting account has multiple WordPress sites, WP-VCD propagates to ALL of them within hours of infection. So "the other site got hacked" is usually them, not a new infection.
How standard cleanups fail
The typical fix attempt:
- Notice
theme-modules.phpor weird code infunctions.php - Remove it
- Site looks clean
- Infection returns within 4 hours
This fails because step 3 left intact:
- The
wp-tmp.phpre-installer - The
wp-includes/wp-vcd.phpruntime - The backdoor user
- The C2 communication infrastructure
Any one of those replants the loader.
The 8-step removal procedure
The procedure that actually works:
Step 1 — Take the site offline
While cleaning, prevent visitors triggering re-infection. Maintenance HTML page:
<!-- /var/www/yoursite/maintenance.html -->
<!DOCTYPE html><html><body><h1>Site under maintenance</h1></body></html>In .htaccess:
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^YOUR\.IP\.ADDRESS$
RewriteRule .* /maintenance.html [L]This shows everyone (except you) the maintenance page during cleanup.
Step 2 — Inventory infected files
cd /var/www/yoursite
# Files with WP-VCD signatures
grep -rl "wp-vcd\|class\.theme-modules\|wp_vcd_settings" --include="*.php" . > /tmp/wpvcd-files.txt
# Recently modified PHP
find . -name "*.php" -mtime -90 -type f >> /tmp/wpvcd-files.txt
sort -u /tmp/wpvcd-files.txt > /tmp/wpvcd-final.txt
wc -l /tmp/wpvcd-final.txtYou should see 5-30 files typically.
Step 3 — Delete all components
# Component 1 & 2 — direct WP-VCD files
find . -name "wp-vcd.php" -delete
find . -name "wp-tmp.php" -delete
find . -name "class.theme-modules.php" -delete
find . -name "theme-modules.php" -delete
# Component 3 — modified theme files
# Manually inspect every PHP file in active theme; revert from clean copyStep 4 — Clean wp-includes/
The malware may have modified wp-includes/post.php, wp-includes/template-loader.php, or other core files. Restore WordPress core fully:
wp core download --skip-content --forceThis re-writes every core file from the official source. Doesn't touch wp-content/.
Step 5 — Clean .htaccess
Replace .htaccess with default WordPress rules. Don't try to identify which rules are malicious — start fresh.
Step 6 — Database cleanup
-- Remove malicious options
DELETE FROM wp_options WHERE option_name LIKE '%wp_vcd%';
DELETE FROM wp_options WHERE option_name LIKE '%wp_seo_data%';
DELETE FROM wp_options WHERE LENGTH(option_value) > 65000 AND autoload = 'yes';
-- Find and remove backdoor users
SELECT u.ID, u.user_login, u.user_email FROM wp_users u
JOIN wp_usermeta um ON u.ID = um.user_id
WHERE um.meta_key = 'wp_capabilities' AND um.meta_value LIKE '%administrator%';
-- For each unrecognized admin:
DELETE FROM wp_users WHERE ID = X;
DELETE FROM wp_usermeta WHERE user_id = X;Step 7 — Reinstall plugins and themes
Reinstall every active plugin and theme from official sources:
wp plugin list --field=name --status=active | xargs -I {} wp plugin install {} --force
wp theme install <theme-slug> --forceIf your active theme was a nulled/pirated theme, replace it with a legitimate version. This is non-negotiable — the original infection came through the nulled theme, and any future "free" download from the same source will re-infect.
Step 8 — Rotate all credentials
# WordPress users
wp user list --field=ID | xargs -I {} wp user reset-password {} --skip-email
# WordPress salts
# Visit https://api.wordpress.org/secret-key/1.1/salt/ and replace salts in wp-config.php
# Database user
# Update mysql user password; update wp-config.php DB_PASSWORDAlso rotate FTP, SSH, and hosting panel passwords.
Verifying the cleanup
48 hours after cleanup, verify no re-infection:
# Check for re-dropped files
find . -name "wp-vcd.php" -o -name "wp-tmp.php" -o -name "class.theme-modules.php"
# Should be empty
# Check for new admins
wp user list --role=administrator
# Check cron for unknown hooks
wp cron event list
# Check for new options
wp option list --search="*wp_vcd*"
wp option list --search="*wp_seo_data*"All these should be empty/contain only what you expect.
Cross-site replication
If your hosting account has multiple WordPress sites, all need this same procedure. WP-VCD will return on the cleaned site if you leave one infected.
# List all WordPress installations on the account
find / -name "wp-config.php" 2>/dev/null | xargs -I {} dirname {}Clean each one.
Prevention
- Never install nulled/pirated themes or plugins. This is the #1 cause of WP-VCD. Buy legitimate, use free GPL alternatives, or contact us.
- File integrity monitoring on
wp-includes/,wp-content/themes/, andwp-content/mu-plugins/ - WAF with rules blocking known WP-VCD callback URLs
- Audit log of admin user creation events
- Daily off-site backups with monthly restore drills
Common mistakes during WP-VCD removal
- Removing only the visible loader — replanted in hours by another component
- Leaving the backdoor user — attacker logs in via cookie and reinstalls
- Not regenerating salts — old salt allows session restoration
- Cleaning only the infected site, not the hosting account — sibling sites re-infect the cleaned one
When to call a specialist
A site with active WP-VCD that has been cleaned 2+ times and keeps coming back has additional vectors that need forensic investigation — possibly a compromised admin account, an SSH key, or a hosting panel compromise. We handle these.
WP-VCD removal — typical resolution 6-10 hours including cross-site verification. For broader hack recovery see hacked website repair.

