23 October 2026
— Why keeping independent journalism online requires more than servers and software
This article explains how Qurium responded to a critical PHP security crisis known as PHP2Shell.
Secure hosting is not free. It requires people, infrastructure, continuous monitoring, technical judgment, and the ability to respond quickly when a critical vulnerability is disclosed outside ordinary working hours. This is particularly important for independent media that cannot simply stop publishing when the Internet becomes an even more broken toy.
It is not easy to explain the importance of security when the sun is shining and everything is working as expected. It is during emergencies that our hosted organizations expect us to act, often without even being aware of the work taking place behind the scenes.
For the first time, we are sharing a detailed account of how Qurium responded to a critical security incident: what we knew, when we learned about it, how quickly we acted, and what our monitoring infrastructure revealed about attackers attempting to exploit the vulnerabilities.
The events surrounding PHP2Shell provide a good example of why keeping independent journalism online requires more than servers and software.
1. A vulnerability years in the making
The PHP Foundation says signs of an underlying out-of-memory problem emerged already in 2024 during follow-up work on a security audit. A reliable exploitation route was then not established, and progress stalled. In August 2026, independent research by Calif, OpenAI, and Google-owned Wiz demonstrated the gravity of the issue. The vulnerabilities were first discovered in July-August 2026, but they were kept secret under a strict embargo for two months to allow the PHP security team time to build patches. But, we guess none can keep a secret for that long, right?
After all, this event is part of a new race unfolding in cybersecurity: technology companies are competing to demonstrate the capabilities of their increasingly powerful AI models. Why not testing the AI models against PHP? After all, PHP is one of the most widely deployed programming languages on the Internet and a nice testing ground for AI-assisted security research.
The PHP codebase was examined using several advanced AI systems, including Anthropic’s Claude Mythos and OpenAI’s security tools. Researchers at Wiz also used frontier AI models, including Google’s Gemini, alongside their own security research infrastructure to help transform previously known memory-management weaknesses into working exploitation chains.
The PHP security team planned to coordinate the disclosure of two critical vulnerabilities on October 22, 2026. However, the information began circulating publicly before the release was fully ready.
2. Source: trust me, bro
Two days before the planned disclosure, on October 20 at approximately 15:20 UTC, a Hacker News user operating under the name “petecooper” published information about two upcoming critical PHP vulnerabilities.

The post disclosed the identifiers CVE-2026-109618 and CVE-2026-109619, together with claims about their severity and expected disclosure date. No technical exploitation instructions were included and the only information available was that all “PHP” is affected, and that really helps, right?
During the preparation of this report, we reached out to Pete Cooper, who explained to us that he was personally notified on Monday 19th October and was verbally told there were no reporting restrictions. Later, Pete released a second posting apologizing for the event.
The existence of the two vulnerabilities was real and the PHP security team reacted by publishing an early security announcement at approximately 19:30 UTC and brought forward the official release of the patches by one day.
But of course, security people make mistakes and at approximately 20:00 UTC, another unexpected disclosure occurred. According to the PHP Foundation, the security research firm Calif mistakenly published a video demonstrating successful exploitation of PHP2Shell against several targets.
We wonder whether “Stefan Esser” of Calif will ever explain how the video ended up online in the first place, particularly given that it reportedly provided enough technical clues for other researchers to reconstruct working proof-of-concept exploits.
There is also a broader question: why was the underlying vulnerability, first identified in 2024, left unresolved until August 2026, when researchers finally demonstrated its potential for remote code execution?
If a prematurely published demonstration could provide others with enough information to develop working exploits, it raises uncomfortable questions about the disclosure process, the handling of known security weaknesses, and why the risks were not addressed sooner.


Although the video was quickly removed, copies began circulating on social media. The demonstration revealed additional technical clues about the vulnerabilities, helping other researchers to reconstruct exploitation techniques before the official patches became available! Well, at least we knew what was coming, thanks!
In the following hours, researchers began publishing PHP2Shell code and scanners on GitHub.
Some implementations attempted to reproduce the underlying memory-corruption vulnerabilities, while others simply tested PHP’s session upload-progress functionality or searched for related weaknesses. Not all the publicly available code was capable of achieving remote code execution.
(Update October 24) We finally got the time to watch the full video “The race to the first exploit of php2shell” by Fabian Fäßler (LiveOverflow). Do not miss it! The video shows how the clues left in Calif demonstration video of Ryan Austin (lcfr_hax) can be used to build a proof-of-concept exploit.
Information about two critical vulnerabilities was spreading across the Internet, technical exploitation details became available, while the official patches had not yet been released.
3. How PHP2Shell works
PHP2Shell refers to two vulnerabilities, CVE-2026-109618 and CVE-2026-109619, affecting PHP’s internal memory management and error handling. In the security space these are “use-after-free conditions attacks”.
The underlying problem involves PHP’s handling of fatal errors, especially out-of-memory conditions. Under particular failure conditions, PHP may retain references to memory released during an aborted request. When a subsequent request accesses that stale information, the result can be memory disclosure, memory corruption or, through more sophisticated exploitation techniques, remote code execution.
An attacker may attempt to exploit this behavior by 1) sending specially constructed HTTP requests designed to trigger an abnormal memory-management condition, followed by 2) additional requests that interact with the corrupted internal state.
Researchers demonstrated several exploitation approaches, including attacks involving:
- PHP session upload-progress processing
- session unserialization
- fatal-error handling
- OPcache
The exact conditions required depend on the PHP version, server configuration, request-processing environment and memory behavior. In some scenarios, attackers may be able to extract sensitive information from process memory, including credentials or authentication tokens. More sophisticated exploitation chains can potentially lead to the execution of commands on the affected server.
This means the vulnerability is not necessarily caused by insecure WordPress, Drupal or Joomla application code. The weakness exists in PHP itself.
What could we detect?
Our initial understanding was that we should start monitoring the increase of any HTTP multipart requests across our infrastructure. Multipart requests are normally used for uploading files or submitting forms. They are legitimate and extremely common, but several PHP2Shell exploitation techniques also rely on carefully constructed multipart requests.
We therefore began examining unusual multipart bodies, PHP session upload-progress parameters, suspicious upload filenames and repeated requests containing recognizable exploitation markers.
Although an ordinary multipart request is not evidence of an attack, the combination of request structure, payload content, source information and HTTP response data can provide strong indicators of exploitation attempts.
4. Qurium’s response: from alert to complete deployment
Qurium received the first information about the “trust me, bro“ security event on Tuesday, October 20, at approximately 21:30 GMT+2 (19:30 UTC).
At that point, the full technical details were not yet publicly available, and there were no official PHP security patches to install.
Our assessment and preparation of temporary mitigation measures began immediately.
We did not have a complete understanding of how the vulnerabilities could be exploited, but we knew enough to identify potentially exposed PHP functionality and begin preparing defensive changes.
Between midnight and 03:00AM local time on October 21, just a few hours after receiving the first warning, Qurium deployed hundreds of temporary PHP configuration mitigations across our infrastructure.
These changes were designed to reduce exposure while we were waiting for the PHP security team to release patches.
At 09:00 AM local time, we implemented a second round of protections through our web application firewall infrastructure. The second round of protections was deployed in our custom CDN that protects a large majority of our hosted sites. We added additional WAF rules that restricted multipart HTTP uploads associated with potentially dangerous request patterns. By that point, only 11 hours and 30 minutes had passed since we first learned about the vulnerabilities.
At 12:00PM , we sent our first notification to all hosted partners, explaining the situation and the temporary security measures already in place. The official PHP security patches were released at approximately 16:00 GMT+2 on October 21, 18 hours and 30 minutes after we became aware of the “Trust me, bro” initial warning.
After the official patches were released, Qurium immediately deployed the security updates across all PHP installations and restarted hundreds of affected services, including websites, mail services and cloud-storage applications. In 30 minutes, all Qurium infrastructure was patched.
This was a good moment to send a second notification to our hosted partners confirming that the security updates had been applied and that the necessary service restarts did not caused any major traffic disruptions.
Timeline of Qurium’s security response
| Date and time (GMT+2) | Security action | Time since first alert |
|---|---|---|
| October 20, 21:30PM | First warning received; exposure assessment begins | 0 |
| October 21, 00:00–03:00AM | Temporary PHP configuration mitigations deployed | 2h 30m–5h 30m |
| October 21, 09:00AM | Additional multipart WAF protections deployed | 11h 30m |
| October 21, 12:00PM | First notification sent to hosted partners | 14h 30m |
| October 21, 16:00PM | Official PHP security patches released; deployment begins | 18h 30m |
| October 21, 16:30PM | Second notification sent. All infrastructure patched; | 19 hours |
But the most important operational milestone was not simply installing the patches. It was the ability to assess the situation, deploy temporary protections before official fixes existed, communicate with partners and complete infrastructure-wide patching within approximately 30 minutes of the security release.
None of these actions happened automatically.
5. Watching the attackers
But the work was not over, while temporary mitigations were being deployed and the official patches were being prepared, we began collecting and examining suspicious HTTP requests targeting the websites hosted on our infrastructure. Who does not want to know who is trying to exploit PHP2Shell, right?
Qurium operates its own monitoring and traffic-analysis infrastructure, allowing us to inspect incoming HTTP requests and correlate them with information about their sources, destinations and behavior.
Our enriched logs include request timestamps, source IP addresses, autonomous system numbers (ASNs), geographical information, HTTP methods, request bodies, response codes and web application firewall decisions. Each request includes close to 100 different parameters that we use for mitigation and forensic analysis.
All this information allows us to reconstruct suspicious activity and identify recognizable exploit patterns.
The first attacks
In our initial analytical dataset, the first retained PHP2Shell-related request was recorded on October 21, 2026, at 06:07:42 UTC, targeting the website of Arab Reporters for Investigative Journalism (www.arij.net).
The request originated from IP address 194.195.91[.]16, associated in our logs with AS206092, F.N.S. Holdings Limited. In the past we have associated AS206092 (SECFIREWALLAS), operated by F.N.S. Holdings Limited in Cyprus, to ExpressVPN. ExpressVPN has been part of Kape Technologies since 2021.
The payload belonged to a family we classify as JACKAL-UAF, containing multipart request structures associated with attempts to manipulate PHP’s internal memory.
As we expanded our analysis, we recovered additional requests and payload families from our logs.
At the time of writing, our latest PHP2Shell analysis contains 236 suspicious HTTP requests originating from 41 logged source IP addresses, that we have grouped into 55 normalized payload clusters.

We have identified a total of 37 distinct targeted websites.
Different attackers, different techniques
Our captured traffic reveals that not everyone was testing PHP2Shell in the same way.
Some requests were relatively simple probes attempting to determine whether PHP session upload-progress functionality was accessible. Others contained serialized PHP objects or recognizable markers designed to identify particular application behaviors.
More sophisticated requests contained binary structures and command-execution strings, indicating attempts to reproduce memory-corruption exploitation techniques.
By analyzing the content of these requests, we identified several recognizable attack families:
JACKAL-UAF: This family includes large multipart requests containing specially constructed binary data and command-execution markers. Some samples include commands such as id and uname -a, which are commonly used to verify whether an attacker has gained the ability to execute commands on a remote system.
NUCLEI-LFI: These requests attempt to combine PHP session upload-progress handling with local file inclusion.
The objective is to place recognizable PHP code into session-related data and determine whether another application vulnerability can cause that code to execute.
We found out that some payloads match distinctive construction patterns found in the publicly available php2shellbt.py scanner.
NUCLEI-WRITE: This family contains multipart uploads with specially constructed PHP session-serialization strings.
The requests appear designed to test whether PHP applications process session data using incompatible serialization formats.
Their payload structure also matches public code from the php2shellbt.py scanner.
P2S-SESSION: These requests contain serialized PHP object structures embedded in multipart upload parameters.
The samples appear designed to probe PHP session-handling behavior rather than directly execute operating-system commands.
P2S-PROBE: These requests are relatively simple attempts to test PHP’s session upload-progress functionality.
They contain distinctive multipart boundaries and test files but do not independently demonstrate memory corruption or remote code execution.
SAFENET-PHP: This family uses recognizable multipart boundaries and PHP session upload-progress parameters.
The observed payloads are consistent with automated vulnerability probing.
Other and Unattributed Payloads: Not every request can be associated with a known public tool. More forensic work is needed to identify the modified copies of existing scanners or new independently developed exploitation code.
A full list of the repositories we identified used in the attacks:
PHP2Shell (CVE-2026-109618) - GitHub Repositories
[1] 0x4148 - PHP2Shell Exploitation Lab
https://github[.]com/0x4148/CVE-2026-109618-php2shell-lab
[2] scallydima - PHP2Shell Proof of Concept
https://github[.]com/scallydima/php2shell-poc
[3] al4n4n - PHP2Shell Proof of Concept
https://github[.]com/al4n4n/php2shell
[4] pentestershell - PHP2Shell Exploit / Testing Tool
https://github[.]com/pentestershell/php2shellbt
[5] JoasASantos - PHP2Shell Vulnerability Scanner (sig: php2shellProbe)
https://github[.]com/JoasASantos/php2shell-scanner
F
[6] Ademking - PHP2Shell Nuclei Detection Templates
https://github[.]com/Ademking/php2shell-nuclei-templates
[7] Jackalsyn - PHP2Shell Proof of Concept. (Really?)
https://jackalsyn[.]com/posts/php-up-2026.html
[8] Iknow - Not php2shell :)
https://github.com/ikow/php2shell-poc
The infrastructure behind the requests
What is more interesting is what we see when we look into the autonomous systems and hosting providers associated with the logged source addresses.
Among the networks observed in our earlier dataset were Datacamp, F.n.s. Holdings, Contabo, Pittqiao Network Information, RouterHosting and other commercial hosting providers.

An aggregated view of the exploitation activity
| ASN | Network operator | Requests | Victims | Source IPs |
|---|---|---|---|---|
| AS53667 | FranTech Solutions | 49 | 1 | 1 |
| AS399486 | 12651980 CANADA INC. | 30 | 3 | 1 |
| AS138995 | Antbox Networks Limited | 23 | 2 | 1 |
| AS206092 | F.N.S. Holdings Limited (ExpressVPN) | 20 | 1 | 17 |
| AS212238 | Datacamp Limited | 18 | 1 | 1 |
| AS42159 | Zemlyaniy Dmitro Leonidovich | 14 | 1 | 1 |
| AS151592 | PT Awan Data Teknologi | 12 | 1 | 1 |
| AS14061 | DigitalOcean, LLC | 11 | 3 | 2 |
| AS11878 | tzulo, inc. | 9 | 1 | 1 |
| AS14956 | RouterHosting LLC | 6 | 3 | 1 |
| AS197170 | TechTies Inc. | 6 | 6 | 1 |
| AS215730 | H2nexus Cloud Services – Fzco | 6 | 6 | 1 |
| AS12735 | TurkNet Iletisim Hizmetleri A.S. | 6 | 6 | 1 |
| AS48753 | Ava Host Srl | 5 | 1 | 1 |
| AS51167 | Contabo GmbH | 4 | 1 | 1 |
| AS209101 | IP Vendetta Inc. | 4 | 2 | 1 |
| AS8075 | Microsoft Corporation | 4 | 1 | 2 |
| AS16509 | Amazon.com, Inc. | 2 | 1 | 1 |
| AS14618 | Amazon.com, Inc. | 2 | 1 | 1 |
| AS141114 | PT Super Media Indonesia | 2 | 2 | 1 |
| AS203020 | HostRoyale Technologies Pvt Ltd | 1 | 1 | 1 |
| AS396982 | Google LLC | 1 | 1 | 1 |
| AS212285 | Linyit Net Telekomunikasyon Hizmetleri Sanayi ve Ticaret Ltd. Sti. | 1 | 1 | 1 |
| TOTAL | 23 ASNs | 236 | 37 unique | 41 |
6. Why we are disclosing this information
We are publishing this analysis because the information collected by our infrastructure can help others to identify and mitigate similar attacks.
Qurium protects independent media organizations and human rights groups, but the underlying vulnerabilities affect a much wider Internet ecosystem.
Other hosting providers, system administrators and organizations running PHP may encounter the same exploitation attempts.
7. The cost of staying online
Our monitoring infrastructure detected 20 php2Shell-related requests originating from 17 IP addresses before the official security patches were released on 21 October. The first attempt was recorded at 06:38 UTC, more than seven hours before the patches became available. All 20 requests targeted the website of Arab Reporters for Investigative Journalism (ARIJ).
All 20 pre-patch requests originated from AS206092 (F.N.S. Holdings Limited), a provider associated to ExpressVPN. They used 17 different source IPs and targeted the same website.
Following the release of the patches, we recorded another 216 suspicious requests targeting 37 websites.
These findings illustrate why secure hosting requires active monitoring and protective measures even before software vendors release security updates.
During the PHP2Shell incident, Qurium responded within hours, deployed emergency protections overnight and patched its infrastructure within 30 minutes of the official security updates becoming available.
We decided to document this incident to illustrate what we mean by “Secure Hosting” and why it requires sustained investment. Hosting independent media is not simply about providing servers and bandwidth. It means maintaining the expertise, infrastructure and capacity to respond when something goes wrong, often without warning and outside normal working hours. Secure Hosting is about real people.
This work is largely invisible, making its value difficult to demonstrate until an emergency occurs. We hope this example helps our donors and partners to better understand what their support makes possible.
Our partners already lose enough sleep doing journalism and activism. Our job is to make sure their websites don’t give them another reason to stay awake.
Appendix
| Payload | Short signature | Purpose | Long signature (payload) |
|---|---|---|---|
| P1 | php2shellProbe | Test PHP session upload-progress handling using a fixed session identifier. | boundary=----php2shellProbename="PHPSESSID"a1b2c3d4e5f6a7b8c9d0e1f2a3name="PHP_SESSION_UPLOAD_PROGRESS"probename="probe_file"; filename="probe.txt"Content-Type: text/plainX |
| P2 | PHPSESSID=probe | Repeat the upload-progress test using a simplified session identifier. | boundary=----php2shellProbename="PHPSESSID"probename="PHP_SESSION_UPLOAD_PROGRESS"probename="probe_file"; filename="probe.txt"Content-Type: text/plainX |
| P3 | WebKitFormBoundary, pad0 | Test multipart handling using a padding field and a different HTTP client. | boundary=----WebKitFormBoundary0945e1e44576898e313c8854name="PHPSESSID"probename="PHP_SESSION_UPLOAD_PROGRESS"probename="pad0"; filename="p0.txt"Content-Type: text/plainPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP |
| P4 | NucleiWrite, stdClass | Test whether PHP processes serialized-object syntax embedded in multipart filenames. | boundary=----NucleiWrite7KI0eYQE62name="PHPSESSID"nucleiRX7yqpKXTOrIfuqPc8ryBvFZname="PHP_SESSION_UPLOAD_PROGRESS"7KI0eYQE62name="f"; filename="x|O:8:\"stdClass\":0:{}"Content-Type: text/plainZ |
| P5 | NUCLEIPie, <?php echo | Test whether PHP code embedded in multipart filename metadata is executed. | boundary=----NucleiNUCLEIPieXI50Wvaname="PHPSESSID"nucleicOnlK8Zg2xTj70R1Lz1Gy5Rqname="PHP_SESSION_UPLOAD_PROGRESS"NUCLEIPieXI50Wvaname="f"; filename="<?php echo 'NUCLEIPieXI50Wva'; ?>"Content-Type: text/plainZ |
| P6 | PHPSESSID, \x00 | Probe PHP session handling when the session identifier contains a NUL byte. | name="PHPSESSID"\x00 (NUL byte)name="PHP_SESSION_UPLOAD_PROGRESS"name="f"; filename="a.txt" |
