Fake Core Files: Rogue wp-login.php and index.php Clones
By Glenn Lyvers · Updated · 4 min read
You are looking at a directory listing full of files whose names you recognize from every WordPress install you have ever seen. One of them does not belong. It is named to look ordinary, it sits exactly where an ordinary file would sit, and the only reason to suspect it is that you know what should be there and this is one item more than that.
Why naming matters
Most people scanning a directory for something suspicious are looking for something that looks suspicious — an odd name, random characters, a file called shell dot php. Attackers worked that out a long time ago. Naming a backdoor after a core file is free camouflage, and it works on exactly the people most likely to be doing a quick visual check.
The common variations are near misses and relocations. A file called wp-login.php in a directory that should not contain one. An index.php in a folder where WordPress only ever places an empty silence-is-golden stub. Names one character away from real ones, like an extra letter or a hyphen where there should be none. Each blends into a listing perfectly.
Knowing what should be there
The defence is knowing the real inventory, and that is genuinely knowable because WordPress is the same everywhere. The web root holds a specific set of files: the wp-admin and wp-includes directories, wp-content, and a short list of files at the top level including wp-config.php, wp-load.php, wp-settings.php, index.php, xmlrpc.php and a handful of others. Anything else in the root is either something you put there or something you need to explain.
Two specific rules help a lot. WordPress core never places PHP files inside wp-content/uploads, so anything there is wrong by definition. And the empty index.php stubs WordPress scatters through its directories contain a single silence comment and nothing else — one that contains actual code is not a stub.
Comparing against the real thing
You do not have to rely on memory. Download the exact WordPress version you are running from wordpress.org and compare it file by file against your install. Anything present in yours but absent from the clean copy is an addition; anything present in both but different in content has been modified. That is a complete and definitive answer for core, and it takes minutes.
The same approach works for plugins and themes from the repository. My guide on verifying core files against checksums covers the tooling for this, including doing it with WP-CLI in a single command, which is much faster than a manual diff.
Reading a suspicious file
A real core file is readable, well formatted, and full of recognizable WordPress function names and documentation comments. A fake is usually one of two things: obviously obfuscated, with long encoded strings and runtime-assembled function calls, or short and functional in a way core files are not — a few lines that take a parameter from the request and do something with it.
Check the top of the file. Core files carry a documentation header describing their purpose. Check the size, since a genuine core file has a predictable length and a backdoor masquerading as one rarely matches. And check modification time against its neighbours, because core files all share a timestamp from when you last updated, and one file dated differently stands out immediately.
Cleaning up
The safest way to deal with core is to replace it wholesale rather than delete files individually — reinstalling WordPress over the top from a clean copy restores every core file correctly and removes the guesswork. Do the same for plugins and themes from their original sources.
Files that exist outside the clean inventory get deleted, not repaired. Then continue with the rest of the job: check the database for injected content, audit administrator accounts, look at mu-plugins and scheduled tasks for persistence, and rotate every credential the attacker could have read.
Making the next check easier
Once the site is clean, a file integrity baseline turns this whole problem into an automated one. Wordfence and similar tools compare your install against official copies on a schedule and tell you when something appears or changes, which is precisely the check that is tedious to do by hand and trivial to do by machine. My guide on monitoring and long-term protection covers setting it up.
If you are staring at a directory listing and genuinely cannot tell what belongs there, that is a reasonable moment to hand it over rather than delete something important. Working out what is real and what is not is routine work for my malware removal service.
Common questions
Should there be an index.php in every WordPress folder?
WordPress does place empty index.php stubs in many directories to prevent directory listing, so their presence is normal. What matters is the contents: a genuine stub contains a single comment saying silence is golden and nothing else. One containing actual code is not a stub, regardless of its name.
How can I be certain a core file is genuine?
Compare it against the same file from an official WordPress download of your exact version, or run WP-CLI's core verify-checksums command, which checks every core file against official hashes in one pass. That gives you a definitive answer rather than an impression.
Why would there be a second wp-login.php?
There should not be. WordPress has exactly one, in the web root. A copy in another directory is either a leftover from a botched migration or a backdoor wearing a familiar name — and given the choice of names available, the second explanation deserves the benefit of the doubt only after you have read the file.
Can I just delete anything I do not recognize?
In wp-admin and wp-includes, effectively yes, because reinstalling core restores everything legitimate. In wp-content you need more care, since that is where your genuine customizations live. Read before deleting, and keep a backup so a mistake is recoverable.
Will Wordfence catch a fake core file?
Its file comparison is good at exactly this — it knows what core should contain and flags unexpected files in core directories. It is weaker on wp-content, where it cannot know what is legitimate for your site, and on small backdoors appended to otherwise genuine files. Useful, but not a substitute for looking.
More than malware
Most people meet me in an emergency. It isn’t all I do.
I’ve been building and repairing systems since 1995. Whatever brought you here, there’s a good chance I can help with the rest of it too — and you’ll be dealing with the same person either way.
Hacked, but not WordPress?
Joomla, Drupal, Magento, Shopify, PrestaShop, Laravel, Node, IIS and plain HTML — cleaned the same way, priced the same way.
Take a look →Custom builds & AI systems
Plugins, custom applications, website chatbots and automation — built to do exactly what you need, maintained by the person who wrote them.
Take a look →Servers, speed, SEO & accessibility
Migrations, faster load times, technical SEO and accessibility fixes. Measured improvements, with the numbers to show you.
Take a look →Better web hosting
Fast, secure hosting with SSL and backups included at no extra charge. Clear pricing, no long-term contracts, no surprises.
Take a look →Classes & free tools
Rather learn to handle it yourself? I teach this, and I give away the tools I built for my own cleanups.
Take a look →Something else broken?
Half my work is untangling what someone else started, gave up on, or broke. Describe it in plain words and I’ll tell you honestly.
Take a look →Tell me what’s wrong. I’ll tell you what it takes.
No queue, no call centre, no sales pitch — one person who answers, quotes honestly, and does the work.