On 21 October 2026 at 14:00 UTC, PHP released emergency fixes for two critical flaws, CVE-2026-109618 and CVE-2026-109619, known together as PHP2Shell. Both allow remote code execution without a login, they reach back to PHP 5.4, and details had leaked a day earlier. PHP says updating is the only complete fix.
We run a network of 218 honeypot sensors in 39 countries, so we went through every request they received between 17 and 23 October 2026 to see what PHP2Shell activity looks like from the attacker's side. We recorded 10.203 requests associated with PHP2Shell activity, from 86 IP addresses, reaching 211 of our 218 sensors. Most belonged to an older attack chain built on PHP's session upload progress feature and a file inclusion flaw, rather than direct exploitation of the two newly disclosed vulnerabilities. Three quarters came from a botnet that was already attacking us over SSH and added PHP2Shell to its toolkit about 30 hours after the release.
That distinction is worth knowing before you read the alarming headlines: 9.864 of the 10.203 requests (97%) used the older chain, which does not rely on PHP's new memory bugs at all.
The short version
- First request: 08:41 UTC on 21 October, about five hours before the fixes were released, from a scanner that called itself
php2shell-scan. It was already delivering malware. - Nothing earlier: none of our sensors saw matching traffic in the four days before 21 October.
- Fast spread: 100 sensors had been hit 23 hours after the release, and 208 of 218 by the end of 22 October.
- One botnet dominates: a single host sent 7.648 of the 10.203 requests (75%). It belongs to a botnet that spreads mainly over SSH, Telnet and Docker.
- What the attacks do: most write a small PHP loader into a session file through PHP's upload progress feature, then try to load that file through a file inclusion flaw. This chain needs a second weakness in the site.
- Payloads: three download servers handed out scripts, and our sensors captured 9 samples from them.
- What to do: update PHP now, and read PHP's 23 October advisory on session upload progress, which can affect servers that are already updated. Switching off
session.upload_progressalso breaks the chain we saw most.
Timeline: from silence to 208 sensors in a day
- 17 to 20 October: no matching traffic. Amazon reported an exploitation attempt against its own honeypots on 17 October. One of the six addresses Amazon published reached our sensors that day, but with Kibana and MLflow probes, not PHP requests.
- 21 October, 08:41 UTC: the first request, a file upload to
/index.phpfrom 85.11.167.243 with the user agentphp2shell-scan/109618. 23 seconds later our sensor recorded a malware download from 92.118.112.100. This host sent 9 requests to 9 sensors before PHP published its fixes. - 21 October, full day: 76 requests from 12 addresses, reaching 31 sensors.
- 22 October: 2.560 requests from 66 addresses. The 100th sensor was hit at 13:14 UTC, and by midnight 208 of 218 had been reached.
- 23 October: 7.567 requests, but from only 15 addresses. The volume rose while the number of senders fell, because one botnet took over.

Requests per hour. Orange is the single botnet host, blue is everyone else.
What the attacks look like

The chain behind most of the traffic: upload, session file, include, download.
We sorted every request into one of five types. Each request counts once, and the five add up to the 10.203 total. Many addresses used more than one type, so the address counts overlap.
- Upload progress request carrying a download command: 6.381 requests from 5 addresses. The request is a file upload form sent to
/index.phpwith a session cookie. One form field,PHP_SESSION_UPLOAD_PROGRESS, holds a short PHP snippet that downloads a shell script and runs it. While an upload is in progress, PHP writes that field's value into the visitor's session file on the server. - Session file inclusion: 3.483 requests from 13 addresses. A plain GET request asks the page to load a session file, for example
/index.php?page=/tmp/sess_<id>or/wp-login.php?file=/var/lib/php/sessions/sess_<id>. The senders cycled through 24 parameter names such aspage,file,path,doc,templateandinclude, hoping one of them feeds an unsafeinclude. If it does, the PHP planted in step one runs. - Upload progress probes without a download: 292 requests from 64 addresses. These send a harmless marker to see how a server reacts.
- Oversized requests: 10 requests from 3 addresses. Chunked uploads padded to 256 KB with deeply nested form arrays. Their shape is consistent with the memory exhaustion techniques reported for
CVE-2026-109618, but the shape alone does not show that a request would trigger the flaw on a given server. - Other requests naming PHP2Shell: 37 requests from 9 addresses, mostly probes for well known PHP paths with "php2shell" in the request.

Two request types make up 9.864 of the 10.203 requests.
The first two types form a chain: write code into a session file, then load it. The busiest sender shows the link directly. In 1.356 of its 1.526 inclusion requests (89%), the GET named the exact session ID that its upload request had set a few seconds earlier on the same sensor.

One captured pair. The session ID from step 1 is the file requested in step 2.
Matching session IDs show the sequence the attacker intended, not that the code ran. By default PHP removes upload progress data as soon as the upload completes (session.upload_progress.cleanup is on), so this technique only works if the inclusion request reaches the session file while the upload is still running, or on a server where cleanup is switched off. That is what the padding fields in these uploads are for: they keep the upload running for longer.
This technique has been documented for years. It only works where the site also has a file inclusion flaw. PHP2Shell may make the upload progress feature dangerous on its own, but a honeypot cannot tell whether a given request would have succeeded against a real vulnerable server, and we make no claim about that. What the data does show is that attackers apply the PHP2Shell name broadly: the busiest loader even passes the word php2shell to the script it downloads.
Where they aimed:
/index.phpreceived 8.548 of the 10.203 requests (84%), and/wp-login.phpreceived 1.296, of which 1.277 were session file inclusion attempts.- Requests arrived on 62 different ports. The standard web ports 80 and 443 received 1.334 of the 10.203 requests (13%). The other 60 ports received 8.869 (87%), led by 8000 (3.314) and 8888 (1.481), Without the busiest host the picture holds: 371 of the remaining 2.555 requests (15%) went to ports 80 and 443. This is not a matter of exposure: all 218 sensors received traffic on all ten of the busiest ports during the week, and ports 443 and 80 carried more traffic overall (3.948.694 and 1.596.584 requests) than 8000 or 8888 (1.143.917 and 524.908). Within our network, the attackers clearly favored alternative web ports. Our data cannot say whether that holds for every PHP server on the internet.
One botnet sent three quarters of the traffic
The host 77.90.185.20 (Limited Network LTD, AS213790, Germany) sent 7.648 of the 10.203 requests (75%): 6.122 upload progress requests with a loader and 1.526 session file inclusion attempts, spread across 208 sensors in 38 countries.
It is not new to us. Our sensors have recorded SSH attacks from it almost every day since our raw records begin on 19 September. Our C2 records show it pointing at three command and control addresses in the same range since 15 August, which suggests one operator moving servers: 217.60.195.113, then 217.60.103.56, and since 3 October 217.60.102.5. In our data, 446 bots pointed at 217.60.102.5 during the week we studied. Most of them spread over SSH (393 bots), Telnet (359) and Docker (339). Individual bots attack over several protocols, so these counts overlap.

The botnet in our dashboard over the 7 days to 24 October: its bots, the one C2 server, the payload it serves and the countries it reached.
On 22 October this one host switched from SSH to web attacks. Its last SSH attempt on our sensors came at 01:55 UTC, its first web request at 20:01 and its first PHP2Shell request at 20:23, about 30 hours after the fixes were released. Alongside PHP2Shell it probed Jupyter and Icecast servers. Before that it had sent 562 to 700 SSH attempts a day from 19 to 21 October, and through 24 October it sent none. Its loader downloads a script from https://217.60.102.5/sh. On 23 October our sensors recorded 9.226 deliveries pointing at that server, against 3.345 to 5.004 a day between 3 and 22 October.

Daily deliveries pointing at the botnet's server. The orange bar is the first full day with PHP2Shell.
When we checked on 24 October, 217.60.102.5 ranked fifth on our live C2 server ranking, where its activity bar for 23 October stands out the same way.

The server's card on our public C2 ranking, 24 October.
Without this host, what remains is 2.555 requests from 85 addresses. That is a better picture of how many different actors were involved.
Scanners, research tools and a cloud burst
- Self named tools: 10 addresses put PHP2Shell in their user agent, with names such as
php2shell-detect/1.0,php2shell-behavioral-check/2.0,php2shell-execandshellflow-php2shell/1.0, and 16 used the word somewhere in their requests. Some are likely researchers or vendors measuring exposure. Others downloaded malware, so a friendly name is no reason to allow a request. - One tool, many cloud addresses: between 12:25 and 13:10 UTC on 22 October, 46 Google Cloud addresses in Germany sent 68 requests, all with the user agent
python-httpx/0.28.1and a harmless probe file. That single burst accounts for 46 of the 86 sender addresses, so counting addresses alone would overstate how many groups were active. - Mostly new addresses: 70 of the 86 senders had never reached our sensors before 21 October. Leaving out the Google Cloud burst, 24 of the remaining 40 were new.
Payloads and download infrastructure
The download commands pointed at three servers. Our sensors fetched what they served and kept a hash of each file.

One of 77.90.185.20's requests as our dashboard stores it. We hid the loader command.
- 217.60.102.5 (Netherlands, AS209373 SWISSNET LLC): serves
/shover HTTPS to 77.90.185.20's victims. It was first seen on 3 October. 1 sample captured. - 92.118.112.100 (United States, AS215540 GLOBAL CONNECTIVITY SOLUTIONS LLP): serves short paths such as
/s,/p,/nand/nfs. Used by 85.11.167.243 from the first hour and later by 45.198.224.169. It was first seen on 14 October. 4 samples captured. - 176.65.139.153 (Netherlands, AS219502 Storm Industries LLC): serves
wget.sh, used by two neighboring addresses in the same network. It was first seen on 14 September. 4 samples captured.
We do not assign malware family names, so we describe these by behavior only: each download command fetches a script and runs it straight away.
What to do now
Update, 24 October 2026: PHP has also disclosed CVE-2026-115560, a separate session upload progress flaw that can affect servers already updated against the original PHP2Shell flaws. It needs an unusual setup: session upload progress is still enabled, the configured session serializer is php_binary or php_serialize, and application code switches it to php at runtime before session_start(). PHP recommends setting session.upload_progress.enabled = 0 until its next regular release where that setup applies. Apply it the same way as the interim settings in step 2 below. Read PHP's 23 October advisory. The 21 October releases remain the correct fix for the two original flaws.
- Update PHP. The fixed releases are 8.5.12, 8.4.27, 8.3.36 and 8.2.35, available from php.net. Branches 7.4 to 8.1 only received source fixes, and older branches are end of life, so plan an upgrade if you run them. Restart every PHP worker afterwards.
- If you cannot update today, apply PHP's interim settings, which include
session.upload_progress.enabled = 0andmemory_limit = -1set so applications cannot override it. Apply them inphp.ini, a PHP FPM pool configuration or the web server configuration, so they take effect before PHP parses the request, and restart every PHP worker. PHP's 21 October advisory warns not to rely onini_set()or FPM.user.inifor this. PHP says these settings reduce exposure but do not make a server safe. Switching off upload progress also stops the session file chain described above. - Check your logs. Ordinary NGINX and Apache access logs do not record POST bodies, so look for
PHP_SESSION_UPLOAD_PROGRESSfields containing PHP code in WAF logs or other request body telemetry. In ordinary access logs, search forsess_paths in query parameters, user agents containing "php2shell" and unexpected requests to PHP endpoints. Check firewall or proxy logs for outbound connections from your web servers to the addresses below. - Block the infrastructure, outbound as well as inbound. Each of the 6.381 download commands we captured named exactly one server, with no fallback address, so blocking those servers breaks these particular infection chains. Attackers can move to other servers or delivery methods, which is why a blocklist needs regular updates. Every paid Whatoblock blocklist includes a Botnet C2 category built from this sensor data and updated hourly, and our integrations page shows the setup for common firewalls.
- Fix file inclusion flaws. If an attacker can control an
includeorrequirepath and load a poisoned session file while the injected code is still there, the chain may result in remote code execution. Fixed paths, validation and allowlists of files prevent it.
Indicators
Download servers
- 217.60.102.5
- 92.118.112.100
- 176.65.139.153
Senders with the most requests
- 77.90.185.20 (Germany, Limited Network LTD): 7.648 requests, upload progress with download and session file inclusion
- 103.204.193.27 (Brazil, HOSTBITS): 336, session file inclusion
- 95.216.5.90 (Finland, Hetzner): 288, session file inclusion
- 31.182.51.55 (Poland, Toya): 287, session file inclusion
- 85.11.167.243 (Netherlands, TechTies): 246, upload progress with download and probes, first sender we saw
- 37.27.209.157 (Finland, Hetzner): 199, session file inclusion
- 170.187.190.236 (Germany, Akamai): 168, session file inclusion
- 212.30.206.158 (Iceland, Mila): 168, session file inclusion
- 134.209.252.157 (Germany, DigitalOcean): 168, session file inclusion
- 185.207.232.121 (Bulgaria, KOMAX): 136, session file inclusion
- 77.91.71.3 (Israel): 79, upload progress probes
- 185.244.155.23 (Iraq, Kurdistan Net): 51, upload progress probes and session file inclusion
- 45.198.224.169 and 45.198.224.110 (Sweden, HostRoyale): 29 together, upload progress with download (the .169 address), probes and oversized requests (the .110 address)
Many senders sit on cloud and hosting networks, and the Google Cloud addresses mentioned earlier were used for under an hour. Treat single cloud addresses as short lived and block them with an expiry rather than permanently.
Frequently asked questions
What is PHP2Shell?
PHP2Shell is the name for two remote code execution flaws in PHP, CVE-2026-109618 and CVE-2026-109619, disclosed on 21 October 2026. One comes from memory corruption when PHP runs out of memory while setting up a request. The other comes from internal state that outlives the request it belongs to. PHP rates both 9.2 under CVSS 4.0.
Which PHP versions are affected?
Every version from PHP 5.4 up to the fixed releases 8.5.12, 8.4.27, 8.3.36 and 8.2.35, across PHP FPM, Apache mod_php, CGI, LiteSpeed and FrankenPHP.
Is PHP2Shell being exploited?
Requests aimed at PHP2Shell reached our sensors from the morning of 21 October, and more than 200 of our 218 sensors were targeted by the next day. Most used the older session upload progress and file inclusion chain, and only 10 resembled the memory exhaustion techniques reported for the new flaws. Honeypots record attempts, not outcomes, so this data cannot confirm successful compromises.
Does turning off session upload progress help?
Yes. It is one of PHP's interim measures for the original flaws, it blocks the session file chain that made up most of the traffic we saw, and it is PHP's recommended protection against CVE-2026-115560 until the next regular release. It does not replace updating, because PHP is clear that no setting fully protects a server from the original flaws.
How do I know if my server was attacked?
Look for the log patterns listed above, PHP processes that crashed or restarted unexpectedly, and new outbound connections from web servers. If you find signs of compromise, rotate the credentials stored on that server.
About this data
- Window: 17 to 23 October 2026, UTC, starting four days before disclosure.
- Sensors: 218 sensors in 39 countries that answer like ordinary internet services. They do not run a vulnerable PHP build, so they record what attackers send, not whether it would work.
- What we counted: we decoded every request and counted it if it contained the
PHP_SESSION_UPLOAD_PROGRESSfield, the word "php2shell", or a deeply nested array body (6.783 requests from 76 addresses). We also counted requests that try to load a PHP session file (3.420 more requests from 11 addresses), because they appeared on 22 October with no history in the previous three weeks, and the busiest sender paired them with its uploads by session ID. Of the 3.483 session file inclusion requests, 63 also matched our initial rules, so only the remaining 3.420 were added. Totals: 10.203 unique requests from 86 addresses. - What we left out: a WordPress plugin upload campaign from hundreds of Amazon cloud addresses that also started on 22 October but uses unrelated plugin flaws, FastCGI configuration injection on port 9000, which we also saw before disclosure, and two ordinary file uploads relayed through an open proxy earlier in October.
- Limits: the counts describe what reached our sensors. One host produced 75% of the requests, so address and server counts say more about the number of actors than request totals do.
Check the live data
Open Scanner Recon with the last 24 hours selected.