Skip to content
Back to the Video Research Library

The Backdoor That Grows Back: Taking Apart a Self-Healing WordPress Infection

Real-World Case9:01
9:01

The player loads from YouTube (privacy-enhanced mode) only after you press play. No YouTube cookies are set before that.

Share:

What this session covers

This session is built from a real cleanup we handled. The site owner had already removed the obvious malicious files twice, and twice they came back within the hour. Nothing in the admin panel looked wrong, the plugins were up to date, and no new administrator accounts existed. The infection was designed to survive exactly this kind of cleanup.

We rebuild the case in our isolated lab with the same structure and harmless stubs in place of the real payload. Starting from the symptom, we trace the trigger to a .user.ini file that prepends a loader to every PHP request. The loader lives inside wp-content/index.php, a file that is supposed to be empty. From there we map every hiding place: a dropper with three hidden copies, spare copies stored inside a ZIP archive, in shared memory and in the database, two guardians that check on each other (a fake advanced-cache.php and a hidden block in the theme), and an hourly cron event that rebuilds whatever is missing.

Key takeaways

  • Find the trigger before you delete anything. A .user.ini or .htaccess prepend runs on every request. Deleting the target file without removing the prepend produces a broken site, and deleting the prepend without the copies produces a reinfection.
  • Map all the copies. Files are only one layer. Check archives, shared memory, the options table and scheduled events for stored copies of the loader.
  • Guardians watch each other. When two components restore one another, removing them one at a time never finishes. They have to go in the same pass, with the cron event removed first.
  • Order matters. Stop the schedule, remove the guardians together, clear every stored copy, then remove the trigger and the loader, then verify after the next cron window.
  • Verify after an hour, not after a minute. A cleanup that looks complete immediately can still be undone by the next scheduled run.

About the lab

Names, domains and payloads from the real case have been replaced by harmless placeholders. The file layout, the persistence mechanisms and the trigger chain are reproduced faithfully so that the checks shown apply to real sites. The written case study with the full teardown order is linked above.

Cleaned your site and it came back?

We find the persistence the previous cleanup missed and remove every layer, with a written report.

Reinfection Investigation