Blog

PHP2Shell, One Week Later: Millions of Attacks, No Confirmed Break-Ins

· 5 min read
cyber_shield_wall_blog_featured_q85

A week ago, two critical PHP vulnerabilities leaked a day before the patch, and the security world braced for the worst. We covered it as it happened in PHP2Shell: Two Critical PHP Flaws Leaked Before the Patch. Every WordPress site runs on PHP. Remote code execution was reportedly possible on every version back to PHP 5. Sansec predicted mass attacks within 15 minutes of the release.

The attacks came, by the million. As of October 23, though, Wordfence and Sophos report no confirmed break-ins. Both of those things are true, and the gap between them is the most useful lesson of the week.

What the week looked like

  • October 17: Amazon’s honeypot network logs an exploitation attempt, four days before any fix is public. Someone already knew.
  • October 20: The advisory leaks. PHP moves its release forward a day.
  • October 21: PHP ships 8.5.12, 8.4.27, 8.3.36 and 8.2.35 at 14:00 UTC. Proof-of-concept code is already circulating. Cloudflare sees tens of thousands of exploit attempts within 45 minutes of disclosure and hundreds of thousands within two hours.
  • October 22: Cloudflare is counting attempts in the millions. Wordfence says its firewall has blocked more than 74,000. Sophos reports a botnet trying to use the bug, then retracts an early claim of a successful compromise.
  • October 23: PHP discloses a third, related flaw, CVE-2026-115560. It needs an unusual session configuration, but it affects even the newly patched releases.
  • October 25: Someone wins a public “steal my bitcoin” challenge built on unpatched PHP. That was a server set up to be attacked, not a victim, but the exploit works in the right conditions.

Why the flood didn’t turn into a wave of break-ins

PHP2Shell is real, critical and remotely exploitable. It’s also hard to exploit, and that’s what this week came down to.

  • It’s a memory bug, and memory bugs are fiddly. One flaw trusts half-finished data after PHP runs out of memory mid-request. The other leaves data behind for the next request on the same worker. Turning that into a shell means guessing memory addresses, and modern systems randomize them (ASLR). Wrong guesses crash workers instead of handing over control.
  • The public exploits need help. Sansec found that they don’t work against a default PHP install. Most need a second serious bug, one that lets an attacker load files from the server.
  • Most of the traffic was scanning. Researchers at Wordfence, Dataminr and others describe probing and attempts to confirm command execution, not successful takeovers. Hunt.io tracked 123 targeted servers and found none exploited.
  • The botnet didn’t land. Sophos identified a Mirai-derived botnet called Potassium trying to load its malware through the bug. Arctic Wolf’s data doesn’t show the requests ever downloading or running it.
  • Defenses were up fast. Cloudflare had firewall rules live within hours, hosts deployed rules of their own, and many managed hosts had patched builds in place the same day.

Why “no confirmed break-ins” isn’t “all clear”

None of that means it was never dangerous, or that it’s over.

  • Exploits get better. VulnCheck says its private exploit for CVE-2026-109618 already works on x86-64 with ASLR on and error display off: a normal production setup. Researchers warn that ASLR slows attackers down. It doesn’t stop them for good.
  • “No confirmed” means “none confirmed.” A quiet compromise on a small site with no monitoring wouldn’t show up in anyone’s telemetry. Amazon says it doesn’t yet know whether any of the attempts it saw succeeded.
  • Old PHP stays exposed. PHP 8.1 and older got no official fix. Those servers are a target that doesn’t get smaller, and they’re where a better exploit will be pointed first.
  • It isn’t finished. The October 23 flaw affects patched versions under an unusual configuration. PHP recommends turning off session.upload_progress.enabled at the server level for it.

Patching fast without panicking

So was it overhyped? Not really. On release day nobody knew how hard the exploit would be, and a critical, unauthenticated bug in the runtime under every WordPress site deserved a fast response. What the week shows is the difference between a fast response and a panicked one.

Fast looks like:

  • Knowing your PHP version and who patches it before the alert arrives. If that’s your host, see Your Host’s PHP Version Is a Security Setting for the questions to ask.
  • Applying the official fix, or confirming your host has, within a day.
  • Verifying it. Your host may patch your current version in place without changing its number, so the build date or the host’s confirmation tells you more than the version alone.
  • Then watching for what an attacker would leave behind: new PHP files, new admin accounts, PHP processes starting shells.

Panicked looks like:

  • Pasting “mitigations” from social media. Several did nothing: setting session.upload_progress.enabled with ini_set() or in .user.ini doesn’t work, and PHP says no configuration change makes an unpatched install safe.
  • Installing unofficial patches. Patchstack warned against them, and installing unknown code on your server during an emergency is its own risk.
  • Switching on WordPress maintenance mode and calling it protection. The bug is in PHP, and PHP still handles every request. A static maintenance page in front of PHP is a different thing.
  • Calling it “all clear” the moment someone posts that nothing happened.

The sites that came through this week fine mostly weren’t the ones with the best emergency response. They were the ones where someone already knew what PHP they ran and who would patch it, so on October 21 the job was a check, not an investigation.

Sources