How to Fix Regenerating index.php Malware in WordPress When Scanners Fail
As someone who has cleaned and secured over 4,500 hacked WordPress websites, I see a lot of complex, deeply buried infections. But if you ask any website owner what the most frustrating, pull-your-hair-out issue is, the answer is almost always the same: index.php malware.
You find the malicious code. You delete it. Your website comes back online, and you breathe a sigh of relief. Then, ten minutes later, your site goes down again. You check the server, and you see the exact same index.php back after removing it.
You are stuck in an endless loop of malware regenerating, and your standard security plugins are completely blind to it.
In this case study, I am going to break down exactly how this persistence mechanism works, why automated scanners fail to detect it, and how we recently used raw server access logs to hunt down a hidden backdoor and permanently break the reinfection cycle for a client.
Key takeaways:
- Understanding how index.php redirect malware hijacks your organic traffic.
- The exact PHP logic and mechanism behind malware regenerating instantly.
- Why automated security scanners often fail to detect hidden droppers.
- A real-world case study of hunting a persistent backdoor using raw server access logs.
- A step-by-step framework to permanently stop the reinfection cycle.
What is index.php Malware?
In the WordPress architecture, the index.php file located in your root directory is the front door to your website. Every single request that isn’t a direct link to a static image or file gets routed through this file. Because of this, it is the holy grail for attackers.
When a site is hit with index.php malware, hackers inject a block of PHP code at the very top of the file, directly before the standard WordPress core functions load.
Typically, this payload acts as a malicious router designed for SEO spam (often Indonesian slot gambling or Japanese keyword spam). The code is highly sophisticated and utilizes cloaking:
-
For Search Engine Bots: It detects the user-agent (like Googlebot) and serves them hidden spam content, forcing your site to rank for illicit keywords.
-
For Organic Traffic: If a real user clicks your link from a Google search, the malware detects the HTTP Referrer and forcefully redirects them to a malicious shortlink.
-
For Direct Visits: If you, the site admin, type your URL directly into the browser, the malware sees there is no referrer and simply loads your normal website.
This cloaking is why many site owners don’t realize they are infected until their SEO traffic completely tanks or Google flags the site with a “Deceptive Site Ahead” warning.
Why is the Malware Regenerating? (index.php back after removing)
The biggest misconception in malware removal is thinking that the infected index.php file is the virus. It isn’t. It is just the symptom.
If you are seeing your index.php back after removing the malicious code, you are dealing with a secondary persistence mechanism. The attacker knows you will eventually find the redirect code and delete it. To protect their access, they plant a separate, hidden script elsewhere on your server.
This secondary script is called a “dropper” or a “re-infector.”
The dropper’s entire job is to monitor your index.php file. The millisecond you clean it, the dropper triggers a function to silently download a fresh copy of the malware and overwrite your clean file. This is the root cause of the malware regenerating loop. Until you find the dropper, you will never secure the site.
The Case Study: When Security Scanners Failed to Detect the Dropper
Recently, a client came to me with a heavily infected e-commerce site. They were exhausted. They had manually cleaned the files, run comprehensive scans with premium security plugins, and even replaced the WordPress core files. Yet, every single time, the site would go down again within the hour.
Step 1: Identifying the Symptoms
I checked the index.php file and found a massive block of obfuscated PHP. It was a classic redirect payload looking for search engine user agents and redirecting organic clicks to a shortlink (s.id/C8dty).
But reading through the payload, I noticed something crucial: there were no file-writing functions in the code itself. There was no file_put_contents(), no fopen(), and no fwrite().
The code in index.php was strictly a router. It didn’t have the capability to rebuild itself. That confirmed we had a ghost in the machine—a hidden dropper executing somewhere else on the server.
Step 2: Why Automated Scanners Failed
The client was incredibly frustrated that their premium security scanner hadn’t caught the issue. But scanners have limitations.
Most security plugins run at the application layer. They look for known malware signatures inside the WordPress environment. However, attackers are smart. They often code their droppers using completely legitimate PHP functions (like cURL or file_get_contents) that standard plugins use every day. If a scanner flagged every file that used those functions, it would break the website with false positives.
Furthermore, I checked the WordPress cron queue (wp-cron.php), and it was completely clean. The attacker wasn’t using WordPress scheduled tasks to trigger the malware regenerating process. They were bypassing WordPress entirely.
Step 3: Hunting the Ghost in the Access Log
To find a threat that bypasses the application, you have to look at the server layer. I bypassed the WordPress dashboard and pulled the raw server access logs.
When you read access logs, 95% of the data is normal noise—Googlebot indexing pages, real users browsing, and admins working in the dashboard. You are hunting for anomalies: specifically, direct HTTP requests to standalone .php files buried in weird directories.
Within a few minutes of filtering, I found the smoking gun right in the middle of the logs:
66.29.132.218 - - [19/Feb/2026:05:41:59 -0800] "GET /wp-content/themes/Divi/ai-app/i18n/user-includes.php HTTP/1.1" 200 90 "-"

Here is why this specific log entry immediately set off alarm bells:
-
Direct File Access: Normal users and search engines have absolutely no business making direct
GETrequests to a PHP file buried deep inside a theme’s internal translation (i18n) directory. -
No Referrer: The request had a blank referrer (
"-"), which is typical for automated bot scripts pinging a backdoor directly. -
The File Name: Divi is a massively popular theme, but it does not natively use a file named
user-includes.phpin that folder. Attackers love hiding payloads inside legitimate-looking theme or plugin directories to blend in. -
The Response Code: It returned an HTTP
200 OKstatus with a tiny90-byteresponse. This meant the script executed perfectly, silently did its job in the background, and returned almost no visual output to the browser.
We had found the backdoor.
The Logic: How the Regenerating Backdoor Worked
I immediately opened /wp-content/themes/Divi/ai-app/i18n/user-includes.php to analyze the code. It was a masterclass in malicious persistence.
Here is the exact logic of how the attacker kept the malware regenerating:
-
The Heartbeat Check: The script contained an array explicitly targeting the absolute server path of the client’s
index.phpfile. It usedfile_get_contents()to read the file and check if the stringC8dty(a piece of the redirect shortlink) was present. -
The Trigger: The attacker had a botnet located at the IP address
66.29.132.218. This botnet was programmed to ping theuser-includes.phpURL every few minutes. -
The Execution: When the client cleaned their site, the string
C8dtydisappeared. The next time the botnet pinged the dropper, the script saw the file was clean. It instantly triggered a customdownloadWithCurl()function, reaching out to an external server (jeetwinbangla.org) to fetch a fresh, raw copy of the redirect malware. -
The Re-Infection: Finally, the dropper used
chmod($path, 0644)to force the correct file permissions, and then usedfile_put_contents()to overwrite the cleanindex.phpwith the freshly downloaded malware.
This was a heartbeat monitor. The moment the client cleaned the file, the heartbeat flatlined, the botnet pinged the dropper, and the malware was instantly resuscitated.
How to Permanently Stop index.php Malware from Regenerating
If you are dealing with your index.php back after removing it, you cannot rely on simply deleting the code from the root directory. You have to break the loop at the server level.
Here is my practical framework for dealing with persistent reinfections:
1. Stop Obsessing Over the Symptom
Delete the malicious code from your index.php file (or replace it with a fresh core file from WordPress.org), but understand that this is only step one. Expect it to come back until you finish the rest of the steps.
2. Interrogate Your Access Logs
Do not rely solely on plugins. Download your raw Apache or Nginx access logs. Look for HTTP 200 responses to standalone .php files located inside your /wp-content/uploads/, /wp-content/themes/, or /wp-content/plugins/ directories that have no referrer. If a file is being accessed directly by strange IP addresses, investigate it immediately.
3. Scan for File-Writing Functions
If you have SSH access to your server (like through cPanel or CWP), use the terminal to grep your entire public_html directory for the PHP functions responsible for the malware regenerating.
Run a command like: grep -Rn "file_put_contents.*index\.php" /path/to/your/site/
This will instantly highlight any hidden scripts trying to overwrite your index file.
4. Kill the Dropper and Block the Botnet
Once you locate the hidden dropper file (like the fake user-includes.php in our case study), delete it permanently. Then, take the IP address that was pinging it from your access logs and block it immediately. This severs the attacker’s automated connection to your server.
Here are two highly effective ways to block the attacker’s IP:
Method A: Server-Level Block via .htaccess
Blocking at the server level is always the most efficient method because it stops the botnet before WordPress even has to load. Place this snippet at the very top of your .htaccess file (above the # BEGIN WordPress line), replacing the IP with the one you found in your logs:
<IfModule mod_authz_core.c>
<RequireAll>
Require all granted
Require not ip 66.29.132.218
</RequireAll>
</IfModule>

Method B: Application-Level Block via Wordfence
If you prefer managing security from the WordPress dashboard, Wordfence makes this incredibly simple:
-
Navigate to Wordfence > Firewall in your WP admin panel.
-
Click on the Blocking tab at the top.
-
Under Block Type, select IP Address.
-
Enter the attacker’s IP (
66.29.132.218), add a quick tracking note like “Malware Dropper Botnet,” and click Block this IP.
5. Audit the Entry Point
Hackers don’t just magically drop files into a Divi theme folder. They exploit vulnerabilities. Once the loop is broken, you must audit your plugins, update all themes, and ensure you aren’t running any nulled software that provided the initial entry point for the backdoor.
Malware is incredibly frustrating, but at the end of the day, it is just code. It follows strict logic. By understanding exactly how the persistence mechanisms function and knowing where to look in your server logs, you can outsmart the attackers, break the loop, and secure your WordPress site for good.
