At a glance
Three backdoors,
in three different places.
What we found in the files
Nine files that
shouldn't have existed.
None of these were plugins or themes, so nothing in the WordPress dashboard showed them. Each one was named to look ordinary.
| Where | What it did | Why it was hard to see |
|---|---|---|
| db.php in the site root | A loader for Japanese SEO spam. It fetched its instructions from a remote server (j250811_13.qlebsack.com), showed spam pages to Google while the owner saw a normal site, could redirect visitors arriving from Japanese Google results, could rewrite robots.txt, and copied itself into two genuine WordPress admin files so it would survive being deleted. | Wrapped in 15 layers of compression and encoding, padded with junk functions. |
| mass.php in the site root | A “mass file uploader”: a web page for uploading any file to the server. | 13 layers of the same wrapping. |
| Seven files in wp-includes/js/dist/script-modules/interactivity/ | Seven copies of the ALFA web shell, which gives full control of files, the database and the server from a browser. A rogue .htaccess sat beside them. | Named about.php, index.php, wp-login.php and alfa-rex with odd extensions (.php7, .php56, .PhP7), inside a folder that normally holds only JavaScript. |
The two admin files db.php wrote itself into were wp-admin/tools.php and wp-admin/includes/class-wp-debug-data.php. That is a common trick: delete the loader, and the copy in a file you'd never think to check puts it back. Replacing WordPress core with an official copy removes both at once, which is why core was replaced rather than repaired.
Nothing here was in a plugin. Every plugin downloaded from WordPress.org still matched its official release exactly. The attacker didn't need to change plugins, because they could write files anywhere.
What we found in the database
Two more ways back in
that no file scan sees.
Deleting files doesn't touch the database. These would have let the attacker back in even after a perfect file cleanup.
A database row can't run by itself, so once the files were gone the token was inert. It was removed anyway: if the attacker ever got code back onto the site, a ready-made login would be waiting for them.
To look for the same thing on your own site, this query lists the two names we found, any option holding code-like content, and any option whose whole value equals a user ID. Change wp_ if your tables use another prefix. A few harmless matches are normal; on a hacked site the last line is what gives the game away.
SELECT option_name, LEFT(option_value, 80) AS value, autoload
FROM wp_options
WHERE option_name IN ('sso_token', '_wp_user_id')
OR option_value REGEXP 'eval\\(|base64_decode|gzinflate|str_rot13'
OR option_value IN (SELECT ID FROM wp_users);
Why the first scan missed it
Looking for bad code
versus checking for good code.
Pattern scan: wrong files
The first scan searched every file for known malicious code. It flagged harmless library files inside plugins as critical, and found none of the nine shells. Code wrapped in 15 layers has no fixed pattern to search for.
Checksums: all nine
WordPress.org publishes a fingerprint of every core file for every release. Comparing each file on the site against that list turned up every extra file in the core folders and every changed one, without needing to recognise the malware at all.
Plugins: cleared
The same check against WordPress.org's plugin checksums showed the flagged library files were identical to the official releases, so they were cleared instead of being deleted and breaking the site.
Our scanner was rebuilt around this on 8 October 2026, the day after we first looked at the site. Run against a copy of it, the new check flagged all nine files as critical and left genuine WordPress files alone.
One more thing this caught: the first attempt to replace core copied the new files over the old ones but left the file that records the version number behind, so WordPress still believed it was 6.8.2. The comparison reported 270 files from 7.1.3 on a site claiming 6.8.2, labelled them genuine code rather than malware, and a proper update from the dashboard finished the job. The scan after that: all 3,338 core files match WordPress 7.1.3, no files added to core folders, no malware signatures.
The cleanup, in order
Files first, then everything
a file cleanup leaves behind.
The order matters. Delete the fake admins while a shell still exists and the shell can make new ones; reset passwords before the sessions are cleared and a stolen session keeps working.
“Planned” means agreed with the site owner and not yet confirmed finished. We update this page as each step is confirmed, rather than marking the whole job done in advance.
How they got in
Not proven, so every
open door gets closed.
The security plugin on the site had stopped recording events long before the attack, so there was no log of the first break-in. We don't know for certain which door was used, and we won't pretend to. What we do know is which doors were open:
Two more file-manager plugins appeared after the break-in, installed by the attacker. That's a common move: if one way back in is found and removed, the others still work. The lesson for any site: a file manager left installed is a door that never closes. Use the host's file manager or SFTP, and remove the plugin when the job is done.
Check your own site
Six checks that would have
caught this weeks earlier.
None of these need special tools. If any of them turns something up, don't delete it straight away: take a copy of the files and database first, so there's a record of what was there.
If you'd rather not do this yourself, our WordPress malware removal service covers exactly this work, files, accounts and database, with a fixed quote before anything starts. See pricing →
More case studies
See all →Wone8 Estates
A Japanese keyword hack: hundreds of injected spam pages removed from the database and files, and Google asked to re-crawl.
Read the case study Malware removal AI scanFound what a manual search missedSafety-training provider
A fake Google CAPTCHA locked every visitor out. A manual search missed the script; an AI-assisted scan found it.
Read the case studyQuestions, answered
WordPress backdoors:
common questions.
What is a WordPress backdoor?
A WordPress backdoor is code or an account an attacker leaves behind so they can get back in after you've changed your password or deleted the obvious malware. It can be a PHP file, a few lines added to a genuine file, a hidden administrator, or a value in the database that some other code reads.
How do I find a backdoor in WordPress?
Compare your files against the official copies instead of reading them. WordPress.org publishes a checksum for every core file and for every version of the plugins it hosts. Any file that doesn't match, or that shouldn't exist at all, is the shortlist. Then check every administrator account and search the options table for values that look like tokens, user IDs or encoded code.
What is a web shell?
A web shell is a PHP file that gives whoever opens it in a browser control of the server: browsing and editing files, uploading more, running commands and changing the database. The ALFA shell found on this site is a common, heavily obfuscated example.
Why didn't my security plugin find the malware?
Pattern-based scanners look for known pieces of malicious code. Shells like these are wrapped in many layers of encoding and junk code, so there is no fixed pattern to match. Comparing files against official checksums doesn't need to recognise the malware, only to notice that a file isn't the one WordPress shipped.
How do hackers create admin users in WordPress?
Usually through code they've already planted, not through the login page. A shell or loader can write a new administrator straight into the database. On this site, seven admin accounts appeared over four days with no administrator logged in beforehand, which is the sign they were created by code.
Is it enough to delete the malicious files?
No. Fake admin accounts, stolen passwords, valid session cookies, application passwords and values left in the database all survive a file cleanup. Each is a way back in. A cleanup isn't finished until every one is removed or reset and the way in is closed.
What does the Japanese keyword hack have to do with a backdoor?
The loader on this site, db.php, was built to serve Japanese spam pages to Google while showing the owner a normal site. The spam is what attackers sell; the backdoor is what keeps them in. We cover a spam-page cleanup in detail in the Wone8 Estates case study.
Can a hacked WordPress site be cleaned without a backup?
Yes. This one was. Core was replaced from an official release and verified file by file, and the database was cleaned in place. A backup from before the infection is useful, but many backups already contain the backdoor, because infections often sit quietly for weeks.
How long can a backdoor go unnoticed?
Weeks or months. On this site, the first fake administrator was created on 17 August 2026 and the compromise was found in the first week of October, about seven weeks later. The security plugin on the site had stopped recording events long before that.