What matters first: The uploads directory should normally contain media, not executable application code. Attackers favour it because it is writable and often survives plugin or core replacement.
What this symptom actually tells you
Deleting one shell does not reveal how it arrived or whether another loader can recreate it. Timestamps, ownership, access logs and related files connect the payload to an entry point.
Capture evidence before changing anything
- List every executable extension and suspicious double extension under uploads.
- Record hashes, timestamps, owner and paths before quarantine.
- Match creation times with access, plugin upload and authentication logs.
- Search for references to the files in cron, options, themes, plugins and server rules.
Most common causes
- Vulnerable upload endpoint: A plugin accepted executable content or bypassed type checks.
- Stolen credentials: An attacker wrote files through SFTP, hosting or WordPress admin.
- Existing backdoor: Another shell or loader generated the uploads payload.
- Misconfigured server: PHP execution is allowed in a directory intended only for media.
Safe diagnostic and repair sequence
- Quarantine evidence outside the web root and block PHP execution in uploads.
- Remove all related persistence and replace compromised components from trusted sources.
- Patch or remove the vulnerable upload path and rotate relevant credentials.
- Scan neighbouring sites and shared hosting accounts using the same system user.
How to choose between the likely causes
Do not treat Vulnerable upload endpoint and Stolen credentials as interchangeable. A plugin accepted executable content or bypassed type checks. By contrast, an attacker wrote files through SFTP, hosting or WordPress admin. Use two checks to separate them: List every executable extension and suspicious double extension under uploads; and record hashes, timestamps, owner and paths before quarantine. Those observations usually show whether the next safe move is to quarantine evidence outside the web root and block PHP execution in uploads or to preserve the current state and widen the investigation.
On a compromised site, containment and cleanup are separate decisions. Preserve the suspicious artefact and access logs before removing persistence, then rotate credentials only after the active path has been closed. Record the exact timestamp, affected URL or transaction, last known good state and every change made during diagnosis. That handover is often what separates a repeatable repair from a temporary disappearance of the symptom.
What not to do
Do not open a web shell in a browser to “see what it does.” Analyse a preserved copy offline and assume every request could trigger attacker logic.
How to verify the repair
- No executable files remain in writable media directories.
- The server refuses execution attempts under uploads.
- Monitoring shows no recreation and the original write path is closed.
A visible symptom disappearing is not enough. Close the incident only when the original failing action, the surrounding business journey and the relevant logs all agree that the fault is gone.
WP REPAIR INCIDENT STANDARD
Safe intervention sequence
Deleting one shell does not reveal how it arrived or whether another loader can recreate it. Timestamps, ownership, access logs and related files connect the payload to an entry point.
- List every executable extension and suspicious double extension under uploads.
- Record hashes, timestamps, owner and paths before quarantine.
- Match creation times with access, plugin upload and authentication logs.
- Search for references to the files in cron, options, themes, plugins and server rules.
What must be verified
- No executable files remain in writable media directories.
- The server refuses execution attempts under uploads.
- Monitoring shows no recreation and the original write path is closed.
Official technical sources
Continue the diagnosis
This guide explains the diagnosis. If the site is affected now, the intervention should preserve a rollback path and verify the real business journey.
See the emergency repair service →ABOUT THIS SYMPTOM
Frequently asked questions about this guide.
Is it enough to just delete the malicious PHP file once I find it in uploads?+
No. Deleting the file removes the immediate payload but does not reveal how it got there or whether a separate loader can simply recreate it. Timestamps, ownership, access logs, and related files need to be traced back to the actual entry point before the incident can be considered closed.
Should I open the suspicious PHP file in a browser to see what it does?+
No, this is explicitly unsafe. A web shell can execute attacker logic the moment it is requested, so it should be analyzed as a preserved offline copy rather than triggered live, on the assumption that any request to it could run malicious code.
Why does malware keep appearing in wp-content/uploads specifically, rather than in plugin or theme folders?+
The uploads directory is normally meant only for media, but it is writable by WordPress and frequently survives full plugin or core replacement, which makes it an attractive target for attackers wanting a payload that persists through cleanup.
If only one site is affected, should other sites on the same server be checked too?+
Yes. When multiple sites share the same hosting account or system user, a vulnerable upload endpoint or stolen credentials on one site can be used to write files into others, so neighbouring sites and accounts sharing that system user should be scanned as well.