Was my WordPress site hacked by PHP2Shell?
You patched PHP for PHP2Shell — but if your site was exposed first, patching doesn’t evict anyone already inside. Here’s a calm, defensive checklist of what to look for in your logs, files and WordPress admin.
By the Presscomet teamPublished 13 min read
On this page
A patch doesn’t undo a break-in
If you’ve just updated PHP for PHP2Shell (the pair of PHP-runtime bugs CVE-2026-109618 and CVE-2026-109619), well done — but notice what the update does and doesn’t do. Patching PHP stops new exploitation. It does nothing to anything an attacker already planted while your site was exposed: a rogue administrator account, a backdoor file in your uploads folder, a scheduled task that re-infects you after every clean-up.
That’s the uncomfortable part of any serious vulnerability. The fix and the clean-up are two different jobs. This guide is only the first one: working out whether anyone got in. It’s deliberately calm and entirely defensive — a list of things to look for, not a way to attack anything. If you turn up a warning sign, the recovery checklist is where you go next.
Who this is for
Were you even exposed?
Before you comb through logs, establish two things: were you running a vulnerable PHP build, and for how long. If the answer to the first is “no” — your host patched or mitigated before you were ever reachable on an unpatched runtime — the rest of this becomes a quick sanity check rather than an investigation.
The dates that frame the window:
1 Aug 2026
Bugs first reported
Roughly when researchers reported the issues to PHP. Security vendors suggest reviewing admin logins back to here as a precaution — not because exploitation started then, but because it’s a safe outer edge.17 Oct 2026
First attempt on record
Amazon’s threat-intelligence team logged an exploitation attempt against its sensors, four days before patches — while the bugs were still under embargo.20–21 Oct 2026
Details leak, then fixes ship
Information spread publicly on 20 October; PHP released 8.5.12, 8.4.27, 8.3.36 and 8.2.35 on 21 October. Mass scanning climbed from thousands of attempts to millions after the announcement.The moment you patched
Your window closes
Your exposure window runs from whenever your server became reachable on an unpatched build until the moment patched PHP workers restarted. If that overlaps 17 October onward, check carefully.
Not sure whether the version you were on was vulnerable? This three-question checker runs entirely in your browser and tells you where a given PHP version stands. It won’t tell you whether you were hacked — nothing automatic can — but it settles the “was I even vulnerable?” question first.
Interactive checker
Am I affected by PHP2Shell?
Runs in your browser · nothing is sent
- 1. PHP version
- 2. Server API
- 3. Hosting
- 4. Verdict
Still unsure what your host actually did, or when? That’s a fair question to put to them directly — our guide on how to ask your host whether they’re patched has a copy-and-paste email, including the key question of when PHP was restarted.
The compromise checklist
Here’s the whole thing as an interactive list. Tick items as you check them; press Found this on anything that looks wrong. Your ticks are saved in this browser, so you can stop and come back. The sections after it explain each group in more detail, including the commands to run.
Interactive checklist
PHP2Shell indicators of compromise
0/14
checked
What the logs reveal
Logs are your best witness, because PHP2Shell’s most reliable triggers leave a shape in them. The attack paths that worry researchers most go through PHP’s multipart parsing and session upload-progress handling, which run before WordPress loads a single line. So the tell-tale requests often land on URLs that have no business receiving an upload at all.
In your web server access log (and your WAF log, if you have one), you’re looking for:
- Multipart POSTs to the wrong places — upload-style requests aimed at your homepage, a feed, or paths that never accept files.
- The
PHP_SESSION_UPLOAD_PROGRESSfield — if your WAF records request bodies or field names, this one is a strong signal because it was a demonstrated remote trigger. - Oversized requests — abnormally large multipart bodies or thousands of form fields.
- Oversized PHPSESSID values — a memory-disclosure technique leaked around 67 KB of server memory per attack through an inflated session cookie.
In the PHP error log, the signature of the out-of-memory technique is a spike of Allowed memory size … exhausted messages, sometimes alongside worker segfaults. On their own these have ordinary causes, so don’t panic at one. What matters is a sudden cluster around your exposure window — then line those timestamps up against the access log and see what was being requested at the same moment.
# Upload-progress trigger and multipart posts in the access log$ grep -i 'PHP_SESSION_UPLOAD_PROGRESS' /var/log/nginx/access.log*$ grep -iE 'multipart/form-data' /var/log/nginx/access.log* | grep ' POST '# Memory-exhaustion spikes and worker crashes in the PHP error log$ grep -iE 'Allowed memory size|exhausted' /var/log/php*-fpm.log*$ grep -iE 'signal 11|segfault|child .* exited' /var/log/php*-fpm.log*# POSTs to the homepage around the exposure window (adjust the date)$ grep ' POST / ' /var/log/nginx/access.log | grep '17/Oct/2026'A WAF in front can hide the evidence
Signs on the server
If an attempt turned into code execution, the next traces are on the filesystem and in the process list. Successful code execution with the web server’s privileges typically shows up as one or more of the following.
- Out-of-place code
- .php files in wp-content/uploads, or unfamiliar files in the web root and mu-plugins
- Spawned processes
- sh, bash, curl, wget, python or perl with php-fpm or Apache as the parent
- Outbound traffic
- Connections from PHP processes to unfamiliar hosts or IPs
- New persistence
- Cron jobs, systemd timers or SSH keys you didn’t add
The media library is the clearest tell: it should contain images, video and documents, never executable PHP. A single .php file in wp-content/uploads is reason enough to treat the site as compromised. The same goes for anything in mu-plugins you can’t explain, since must-use plugins load automatically and can’t be switched off from the admin.
# PHP files where only media should live$ find wp-content/uploads -type f -name '*.php'# PHP files changed since the first recorded attempt$ find . -type f -name '*.php' -newermt '2026-10-17' -not -path './wp-content/cache/*'# Must-use plugins (there may legitimately be none)$ ls -la wp-content/mu-plugins 2>/dev/null# Administrators and when they were created (WP-CLI)$ wp user list --role=administrator --fields=ID,user_login,user_email,user_registered# Core files that differ from the official release$ wp core verify-checksumsNone of this modifies anything — it only lists and compares. If a command above surfaces something you can’t account for, don’t start deleting. Preserving the evidence is what lets you (or a professional) work out how far the intrusion went, and the recovery checklist explains the order to clean up in.
Signs inside WordPress
Some evidence never touches a log you can read — but it surfaces inside WordPress and in Google. These are the signs a non-technical site owner is most likely to notice first, and they’re worth checking even if you have no server access.
Step 1: Unknown administrators
Open Users › All Users and filter by Administrator. An account you didn’t create — especially one registered during your exposure window — is a serious red flag. Note it; don’t delete it yet.Step 2: Plugins you didn’t install
Check Plugins › Installed Plugins and the Must-Use tab. Attackers add plugins to keep a foothold, and must-use plugins are a favourite hiding place because they can’t be deactivated from the dashboard.Step 3: Spam pages and redirects
Searchsite:yourdomain.comfor pages you never wrote — pharma, casino, counterfeit goods or foreign-language spam. Redirects often fire only for visitors arriving from Google, or only on mobile, so you may not see them while logged in.Step 4: Search Console security issues
Open Search Console › Security & Manual Actions › Security issues. A “Hacked: content injection” or similar flag is Google telling you it found something you haven’t.Step 5: Host and antivirus warnings
A malware, spam or resource-abuse notice from your host, or readers reporting that their antivirus blocks your site, is external confirmation worth taking seriously.Step 6: Unexplained admin logins
If you log logins, review successful administrator sign-ins back to 1 August 2026 for odd times, locations or IPs. No login log? Your host’s access logs are the fallback.
Not every scare is a hack
You found something — now what
If you flagged anything above, treat the site as compromised until you’ve proven otherwise. The instinct is to start deleting the scary files immediately; resist it for ten minutes, because deleting evidence makes it far harder to tell how far the attacker got and whether they left a way back in.
Step 1: Contain, don’t delete
Put the site behind maintenance at the server or CDN level, or take it offline. A maintenance-mode plugin isn’t enough — it runs inside the compromised software.Step 2: Preserve the evidence
Snapshot files, a database export and your logs before changing anything. Even an infected copy is useful, and it’s a fallback if the clean-up goes wrong.Step 3: Confirm PHP is patched
There’s no point cleaning while the door is still open. Make sure PHP is on a fixed build (8.5.12, 8.4.27, 8.3.36, 8.2.35 or a vendor backport) and that workers were restarted.Step 4: Rotate every secret
Because PHP2Shell can leak worker memory, assume passwords, tokens and API keys were exposed. Our guide on rotating WordPress security keys and secrets walks through the full list.Step 5: Clean up in order
Follow the WordPress hacked recovery checklist: restore a clean backup from before your exposure window, or rebuild from official sources, then request a Google review.
For a site that handles payments, member accounts or personal data, bring in professional help early — you may have legal duties to work out what was accessed, not just to make the symptoms disappear.
Why PHP2Shell can’t touch Presscomet
PHP2Shell is a bug in the PHP runtime. Presscomet has no PHP runtime — it runs the same wp-admin, block editor, URLs and REST API on Node.js with a single SQLite file — so PHP2Shell and the whole class of PHP-runtime vulnerabilities simply don’t apply to it. There’s no PHP worker memory to leak and no multipart parser to abuse.
That’s a genuine reduction in attack surface, not a magic shield, and it’s worth being honest about the edges. Presscomet still has its own software to keep updated — Node.js, its libraries and the server it runs on — and its own login to protect, so nobody should call it unhackable. It also doesn’t run PHP plugins: the common jobs (SEO, forms, SMTP, redirects, security, custom fields) are built in, but WooCommerce stores aren’t supported. The trade-offs are laid out on our WordPress security page.
Clean first, then consider moving
And if you came through this clean: keep your logs for a few weeks, re-check your administrator list and a site: search next week, and — if you were exposed at all — rotate your secrets as a precaution. Then run the broader WordPress security checklist so the next runtime bug is someone else’s emergency, not yours.
Sources
Facts checked against these sources on October 24, 2026. Things change quickly; the vendor advisory always wins.
- [1]PHP2Shell advisory (indicators of compromise and detection) — Sophos
- [2]PHP2Shell: session upload-progress as a remote trigger — Imperva
- [3]PHP2Shell and WordPress: what to look for — Meow Apps
- [4]PHP2Shell exploitation started days before patches — SecurityWeek
- [5]PHP2Shell FAQ (exploitation status) — watchTowr
- [6]PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 security releases — PHP.net
- [7]FAQ: My site was hacked — WordPress.org Documentation
- [8]Security issues report — Google Search Console Help
Frequently asked questions
How do I tell if my WordPress site was hacked by PHP2Shell?
Check four places. In your web and WAF logs, look for multipart/form-data POSTs to URLs that don’t accept uploads, requests carrying the PHP_SESSION_UPLOAD_PROGRESS field, unusually large multipart bodies, and oversized PHPSESSID values. In the PHP error log, look for spikes of “Allowed memory size … exhausted” and worker segfaults. On the server, look for shells or download tools spawned by php-fpm or Apache, new or modified .php files in wp-content/uploads, and outbound connections to unfamiliar hosts. In WordPress, look for unknown administrators, plugins you didn’t install, spam pages and Search Console security warnings.
If I’ve already patched PHP, do I still need to check for a compromise?
Yes, if your site was online and unpatched at any point while PHP2Shell was being probed. Patching PHP stops new exploitation, but it does nothing to a backdoor, rogue admin account or malicious file that an attacker planted before you patched. The first recorded attempt was 17 October 2026 and fixes shipped on 21 October, so a site exposed during that window should be checked, not assumed clean.
What is the PHP_SESSION_UPLOAD_PROGRESS field and why does it matter?
It’s a field name tied to PHP’s session upload-progress feature, which runs during multipart form parsing — before your application code executes. Several demonstrated PHP2Shell techniques used it as a remote trigger, so requests containing PHP_SESSION_UPLOAD_PROGRESS, especially to pages that never handle uploads, are worth flagging in your logs. Seeing it is not proof of compromise on its own, but it belongs in your review.
Does a spike of “Allowed memory size exhausted” errors mean I was hacked?
Not on its own — memory-exhaustion errors have ordinary causes like heavy plugins or large imports. But one PHP2Shell technique relies on forcing an out-of-memory condition at the wrong moment, so a sudden cluster of memory-exhaustion errors and worker segfaults (for example “exited on signal 11”) around 17–23 October 2026 is a reason to look harder at the same timestamps in your access log.
How far back should I review admin logins?
Security vendors suggest reviewing successful administrator logins back to 1 August 2026 as a precaution, since that’s roughly when the bugs were first reported. Look for logins at odd hours, from unfamiliar locations or IP addresses, or for accounts that shouldn’t have been active. Keep in mind many sites don’t log logins by default, in which case your host’s access logs are the next best record.
I found nothing. Can I be sure my site is clean?
You can be reasonably confident, not certain. Absence of evidence isn’t proof, especially if your logs don’t go back far enough or a WAF sat in front of the origin. Keep your logs for a few weeks, re-check your administrator list and a site: search once more the following week, and watch for host warnings. If your site handles payments or personal data, consider a professional review.
Presscomet keeps your wp-admin, editor, URLs and content, and serves pages without PHP or MySQL. Check your site for free, then migrate in one click — your old site is only ever read.
Keep reading
- SecurityPHP2Shell and WordPress: are you affected, and how do you fix it?
Two critical bugs in PHP itself put almost every WordPress site on an affected runtime until the host patches it. Here’s what happened in plain English, a checker that tells you whether you’re affected, and step-by-step fixes for every kind of hosting.
- SecurityWordPress hacked? A step-by-step recovery checklist
Redirects to spam sites, admin users you never created, a warning from Google or a suspension notice from your host. Here’s the order to do things in, so you clean the site once and it stays clean.
- HostingIs your WordPress host patched for PHP2Shell? What to ask (with an email template)
On most WordPress sites you can’t patch PHP yourself — your host has to. Here’s who is responsible on each kind of hosting, the four questions that get you a real answer, and a ready-to-send email.