rawatweb

How to Find a WordPress Backdoor When Malware Keeps Returning

Malware that returns after cleanup usually means persistence or the entry point remains. Trace the path with evidence instead of deleting files at random.

Editorial map of WordPress files, accounts, cron events, and database checks used to locate malware persistence.

You removed an unfamiliar file, changed passwords, and even installed a scanner. Hours or days later, the file returns, a redirect reappears, or a new spam page is indexed. That pattern usually means one of two things: a persistence mechanism can still write the payload, or the original entry point is still open and the site is being compromised again. Deleting the visible symptom one more time only repeats the cycle.

Short answer: do not begin by deleting the newly returned file. Preserve a fresh snapshot of files, database, hosting logs, CDN logs, and discovery time. Identify what returned and when, then trace accounts and sessions, tokens, cron, core/plugin/theme code, uploads, database records, server configuration, and hosting access in order. Restore from a known-clean source, fix the entry point, revoke risky access, and verify that no remaining mechanism can recreate the payload.

“The malware came back” is not a diagnosis

A recurring finding has several possible causes. A PHP backdoor, vulnerable plugin or theme, unfamiliar administrator, application-password token, WordPress cron event, server scheduled task, stolen hosting credential, contaminated deployment, CDN Worker, or infected administrator device could be writing it again. Sometimes the finding is actually a restore from an infected backup or a scanner repeating a detection on an unchanged file.

Because different causes can produce the same symptom, correlate each indicator with a timeline. Is the exact file returning at the same path? Does its hash and modification time match? Does the site redirect only under certain conditions? Does its return line up with a login, cron job, deployment, or restore? Preserve evidence for each question before changing the system.

Contain risk and preserve evidence first

  1. Notify the host and business owner. If phishing, payments, or customer data are involved, request immediate containment, restrict the dangerous route, and follow the organization’s incident process.
  2. Snapshot files and the database and export logs before their retention window expires. Keep a separate read-only evidence copy; record timestamps, time zone, hashes, who collected it, and actions already taken.
  3. If the site is still serving visitors, use a maintenance or isolation measure approved by the host. Do not shut down the whole service without coordination if that could destroy evidence or interrupt transactions.
  4. Create a working copy that is not publicly accessible. Disable outbound email, payment, webhooks, and production integrations so suspicious code cannot contact customers or alter other systems during analysis.
  5. Do not execute a suspicious file to “see what it does”. Do not upload a sample to a public service if it contains data or credentials. If malware analysis is needed, ask a professional to use an isolated environment.

Build a recurrence timeline

Create one row per finding: path or object name, first and last time seen, hash, reporting source, action taken, time it reappeared, and nearby changes. Normalize server, hosting, CDN, database, and administrator-device clocks to one time zone. File modification times can be manipulated; treat them as clues, not proof.

Compare a pre-cleanup and post-cleanup copy if available. If the hash changed, identify the process writing the file. If the hash is the same but the location changed, look for a loader that makes a copy. If the file did not change but behavior did, inspect a CDN rule, server configuration, cache, JavaScript, or database value. Check whether a scanner is flagging a legitimate unchanged file; do not treat every alert as a backdoor.

Check persistence layer by layer

1. Human access and credentials

Inventory administrator, editor, hosting, SSH/SFTP, DNS, CDN, registrar, deployment-key, backup, and service accounts. Review new users, role changes, recovery email, login times, active sessions, application passwords, and API tokens. A familiar account name does not prove that its session or credentials are still safe.

From a device known to be clean, reset unique passwords for the owner, hosting, SSH/SFTP, database, CDN, DNS, and any service that can write to the site. Enable MFA, revoke unneeded application passwords/tokens, end old sessions, and remove malicious accounts only after confirming that a legitimate owner retains access. If you change passwords from an infected device, an attacker may simply capture the replacement credentials.

2. Core files, plugins, themes, and drop-ins

Compare WordPress core with the official version using wp core verify-checksums. That command compares core checksums; it is not a complete scan of every plugin, theme, upload, or database record. For WordPress.org plugins, wp plugin verify-checksums --all can help, but custom or premium components without public checksums must be compared with a trusted vendor package or source. See the WP-CLI core checksum command, plugin checksum command, and the WordPress guide to security checks with WP-CLI.

Look for new or changed PHP files in the root, wp-admin, wp-includes, plugins/themes, mu-plugins, uploads, cache, and temporary directories. Check wp-config.php, .htaccess, .user.ini, PHP configuration, drop-ins, and files outside normal locations. Do not overwrite every core file before taking a snapshot and confirming the correct version: replacing core does not remove persistence in plugins, themes, the database, or the server.

3. Cron and automation

On an isolated copy, record scheduled WordPress events with wp cron event list and compare unfamiliar hooks with the plugins and themes that are supposed to be installed. Also inspect system cron, hosting scheduled tasks, deployment pipelines, backup jobs, and CDN events. The WP-CLI command lists scheduled WordPress events; it does not show every automation task on the server. See wp cron event list.

Do not delete every cron event without understanding its purpose. A legitimate event may send email, clear cache, or update data. Identify who scheduled the hook, its callback, when the schedule changed, and whether it calls an unapproved file or URL.

4. Database, configuration, and the original entry point

On a working database copy, inspect unfamiliar posts/pages, sitewide options, widgets, custom code, administrator list, active plugins, redirect destinations, and values changed around the incident. Use tools that understand serialized data; raw SQL edits can corrupt serialization or multisite settings. Review access/error logs, hosting-panel logins, unusual POST requests, WAF/CDN activity, FTP users, backups, and integrations. Ask the provider to check logs you cannot access.

Find the weakness that allowed the first write: an outdated component, weak or reused credentials, an executable upload path, an old vendor account, overly broad permissions, or a token that was never revoked. If you do not know the initial entry point, do not call the incident resolved just because the payload is gone.

Connect each returning change to the process that wrote it

Make a suspected backdoor testable with evidence. Build a table with “finding”, “who/process can write it”, “supporting log”, “next safe test”, and “decision owner”. For a new file, compare its path with the system owner and FTP/SFTP/deployment logs; for a new post, compare the author ID with logins and role changes; for a redirect, correlate the request ID between CDN and origin. If a log is unavailable, state that limitation and ask the host to review the sources that remain.

Inspect a copy with plugins and themes disabled only if that is safe for the investigation; some WordPress configurations need active components to read the database or reproduce behavior. Record each change to the copy so comparisons remain valid. Do not treat “the symptom stops when a plugin is disabled” as proof that the plugin is malicious: dependencies, cache, or conditional rules may also change. Test one component at a time and compare the result with files, vendor code, and logs.

Clean up in a reversible order

  1. Select a trusted clean source from a backup that predates the compromise or an official vendor package, after checking when the incident likely began.
  2. Fix or disable the entry point on staging; update or replace unsupported components. Remove an unfamiliar file only after preserving evidence and verifying ownership.
  3. Revoke risky access and rotate secrets from a clean device. Check integration keys, database users, SSH keys, and service accounts—not just WordPress passwords.
  4. Restore only necessary business data after reviewing content, accounts, and options. Do not import an old database wholesale without considering that persistence may be stored in it.
  5. Test core functions, sign-in, forms, payments, cron, email, and affected routes on staging. Compare files and database records with a trusted baseline.
  6. Apply the same fix to production during an approved change window, retain a pre-change backup, and verify the outcome again.

Prove that the fix survives

Schedule repeated checks during a monitoring period chosen by the team. Compare hashes of important files, accounts, plugins/themes, cron, redirects, indexed pages, and logs. Repeat tests after cache expiry and scheduled jobs have run; a check immediately after restore can miss a task that runs later. Keep dated results and state exactly what each check covered.

If Search Console reports a Security Issue, request a review only after every finding and entry point is fixed. Google may show additional sample URLs; check the whole site, not only the sample. Google’s owner guidance also recommends monitoring logs and unexpected changes (preventing malware infection). For a broader incident workflow that includes preserving evidence and containment, read our guide to a hacked WordPress site. For visible symptoms, read signs your website may have malware.

Mistakes that let malware return

  • Removing one file or changing the WordPress password while leaving a hosting account, token, cron, vulnerable plugin, or active session untouched.
  • Restoring a backup based only on its filename instead of checking when the compromise began.
  • Running scanners repeatedly without comparing hashes, logs, or the process that writes a file.
  • Replacing core files and calling it cleanup while wp-content, the database, CDN, and server are not reviewed.
  • Deleting every cron event or PHP file without identifying its owner and impact.
  • Changing permissions to 777 for convenience, making it easier for an existing process to write files again.
  • Sending a replacement password through chat or changing it from a device that has not been checked.

Will reinstalling WordPress core remove a backdoor? Not necessarily. Clean core files do not automatically clean plugins, themes, mu-plugins, uploads, the database, accounts, server cron, or the CDN.

Why did malware return after I changed my password? The password may be only one of several credentials. A session, application password, hosting account, cron job, or still-open vulnerability can preserve access.

Is every unfamiliar PHP file malware? No. A theme, plugin, or application may legitimately include PHP files. Compare location, checksum, owner, time, contents, and package source before deleting one.

When should I get professional help? Escalate if files keep reappearing, an unfamiliar hosting login exists, the database or payments may be affected, you lack logs or a clean baseline, or the site behaves differently after restoration.

If malware keeps returning and you cannot identify what recreates it, request WordPress emergency recovery help to trace the evidence before making destructive changes.

#WordPress backdoor #recurring malware #persistence #incident response
Let's talk about your website

Does any of this look like your website?

Tell us on WhatsApp. We look first, explain what needs fixing, then you decide. For a fuller picture, request the free audit.

Chat with us