Quick Answer: The PHP2Shell exploit chain pairs remote code execution (CVE-2026-109618/CVE-2026-109619) with the Fragnesia kernel privilege escalation (CVE-2026-46300). Dream researchers found it used in a single unauthenticated HTTP request against exposed firewall management interfaces. The campaign rooted 25 servers, including a US government-affiliated environment, and then attacked that organization's Active Directory.

The PHP2Shell exploit chain didn't stop at the firewall. According to Dream's research write-up, the attacker used a rooted device as a launch point into a government-affiliated organization's internal network. Dream's artifacts show an operation that ran from exploit development in a lab to persistent access inside an Active Directory domain. The most useful lesson isn't the exploit itself. It's how little stood between a management web interface and an identity system.

How the Two-Stage Chain Works

The attack needed two separate bugs, and neither alone gave root. The first stage was remote code execution through PHP's session.upload_progress mechanism on the firewall's appweb management server. The firewall ran PHP 8.0.30 with a high memory limit, which let the attacker push the memory corruption stages through. Dream describes four orchestrated requests:

  1. Memory exhaustion: Crafted multipart POST requests with oversized filenames pushed allocation to roughly 383MB, forcing a predictable heap layout.
  2. Information leak: A forged stale session ID length triggered an out-of-bounds read. The leaked pointer came back in a Set-Cookie header, giving the base address of libphp.so.
  3. Stale reference setup: A second memory pressure round (around 500MB) left a dangling reference the attacker could later forge.
  4. Code execution: A forged PHP HashTable entry pointed its destructor at zif_system, so PHP's own cleanup handler ran attacker commands as the nobody user.

That gets code execution, but not root. SELinux confines httpd_t from modifying system files. So the attacker chained in Fragnesia, a kernel flaw in the XFRM ESP-in-TCP subsystem. It writes through the page cache to overwrite /etc/pam.d/su with a pam_permit.so rule, which accepts any password. Because that PAM file is only 774 bytes, the exploit used a per-byte splicing variant to write it precisely. After that, su root simply works.

Both stages ran inside a single B2 request. Dream measured the full chain, from unauthenticated HTTPS connection to persistent root webshell, at under 15 minutes.

Here's the part most advisories skip: the chain is loud. Dream's first rooted firewall crashed shortly after exploitation, likely from the roughly 900MB of exploit traffic, and never came back online. A noisy exploit that works is still noisy, and an attacker who crashes a target loses that foothold for good.

Why Version Profiling Mattered More Than the Exploit

Here's what makes this campaign more than a spray-and-pray. The exploit needs precise memory offsets that change between firewall OS versions: the address of zval_ptr_dtor, the address of zif_system, HashTable structure sizes, and heap geometry parameters. Get any of them wrong and the exploit fails or crashes the process.

Dream recovered 11 JSON version profile files, one per firewall OS version the attacker had tested. Each contained offsets extracted from the specific libphp.so build, along with SHA256 hashes and ELF build IDs. The distinction between profile types matters:

Profile StatusCount in ArtifactsWhat It MeansRisk to Attacker
Calibrated1 (8.0.30 base)Tested against a running VM of that versionLow; memory geometry confirmed
Provisional8 (8.0.30 variants)Offsets computed from binary, not live-testedHigher; may crash or fail
Provisional2 (7.4.33 branch)RCE as nobody verified, full chain not calibratedHigher; partial coverage

Most people assume a working exploit is the hard part. The artifacts suggest the opposite here. The attacker spent their effort on version coverage, not on a single clever payload. That's a scaling problem, and it's why patching one version doesn't close the exposure for the others.

Here's where it gets interesting for defenders. A profile library turns a one-off exploit into a fingerprint-and-fire operation. Anyone who can tell which version you run can match you to a profile.

The Funnel: From 19,000 Exposed Firewalls to 24 Roots

The targeting followed a clear funnel. Dream's artifacts show each stage narrowing the pool:

  • Discovery: The attacker used FOFA, a Chinese internet asset search engine similar to Shodan, to find about 19,000 internet-facing firewalls from the vendor worldwide. Devices were identified through certificate fingerprints and HTTP response signatures.
  • Version fingerprinting: A custom scanner ran 200 concurrent threads against those targets. About 5,000 responded with version information.
  • Geographic and version filtering: The list narrowed to US, Japan, Taiwan, and South Korea devices running the newer release branches with PHP 8.0.30. That left 240 targets.
  • Automated exploitation: A batch runner hit five targets at a time, with a 1800-second timeout each. Successful runs planted a 103-byte PHP webshell in a public directory and verified root by running id.

That produced 24 rooted firewalls, and later 25 with the management server. The batch automation made the campaign efficient, but it also left a clear trail. Dream notes that 22 of the 24 were simply parked: the webshell stayed, nothing else was installed, and the attacker could return whenever they wanted.

Most teams treat that as the end of the story. It wasn't. Two rooted devices turned out to be different.

Where the Campaign Turned: From Firewall to Active Directory

Two of the rooted firewalls belonged to a US government-affiliated organization. Dream says the running configuration from the first one exposed the network's topology, including domain controllers, a central firewall management server, a Keycloak SSO server, a GitLab instance, VPN gateways, and the Active Directory domain.

The first device crashed, so the attacker went back for the second. It had timed out during the original batch, but the attacker ran a dedicated campaign against it on October 24. Within hours, they had built an 8-port reverse SSH tunnel back to their infrastructure. The tunnel forwarded LDAP, LDAPS, and RDP to the domain controllers, plus the firewall management server, VPN infrastructure, and a SOCKS5 proxy for arbitrary internal access.

The tunnel was wrapped in a systemd service and an rc.local boot hook, so it survived reboots and reconnected on its own. Persistence was built in before the attacker touched anything else.

Then the attacker used the management server to reach the other systems. Because that server already had LDAP connectivity to Active Directory (it needs that to authenticate VPN users), it became the launch point for domain attacks. Dream's artifacts confirm credential extraction and directory enumeration.

This is the counter-intuitive finding. The common advice treats a firewall as a perimeter device whose compromise is a network problem. In this case, the firewall was a routing point into identity infrastructure, and the management server was a privileged bridge to Active Directory. Compromising the firewall was really compromising the identity plane. That changes your containment plan: rotating the firewall's own credentials isn't enough if the management server still holds LDAP bind accounts.

What the AI Evidence Does and Doesn't Prove

Dream reports signs of AI-assisted tooling: Claude Code was installed, an offensive security platform called aiscan was configured with DeepSeek and Kimi API keys, and FOFA keys were present. Dream also points to the consistency of code structure and commenting across about 40 post-exploitation scripts as evidence of AI-assisted development.

Dream is careful here, and you should be too. The researchers say they have no direct evidence that AI wrote the exploit itself, and they describe the operation as not fully autonomous. Attribution to a Chinese AI-assisted campaign is Dream's assessment, not a confirmed fact. What matters for your team is less the attribution and more the capability: a small operator can now produce a lot of consistent tooling quickly.

What Defenders Should Do Now

Start with the exposure you didn't know you had. Management interfaces should not sit on the public internet. If your firewall's web admin console is reachable from outside, that's your first finding, and it's the entry point Dream describes.

Next, check for signs of compromise specific to this chain:

  1. Search web-accessible directories on the firewall for unfamiliar PHP files, especially small ones around 100 bytes.
  2. Review /etc/pam.d/su for any pam_permit.so entries. Its presence means the Fragnesia path likely succeeded.
  3. Inspect systemd units and rc.local for unexpected SSH tunnels or forwarding rules.
  4. Look at the management server's LDAP and Active Directory logs for enumeration and unusual credential use.

Then treat any affected firewall as an identity incident. Rotate every credential the device or its management server could read, including LDAP bind accounts, VPN service accounts, and SSO secrets. Patching closes the door, but rotation tells you what the attacker might already have taken.

Finally, be honest about the limits. Dream didn't name the vendor, and the affected versions aren't public in the source, so you'll need to check with your vendor directly. If you can't verify your version, assume exposure until you can.

Frequently Asked Questions

What is the PHP2Shell exploit chain?

The PHP2Shell exploit chain is a remote code execution flaw (CVE-2026-109618/CVE-2026-109619) that abuses PHP's session upload progress feature to run commands as the nobody user. In this campaign, it was paired with the Fragnesia kernel flaw (CVE-2026-46300) to reach root. Both ran in one unauthenticated HTTP request against vulnerable firewall management interfaces.

How do attackers root firewalls with a single request?

Attackers combine memory corruption in PHP with a page-cache write in the Linux kernel. The first stage gives code execution as nobody. The second overwrites /etc/pam.d/su with a permissive rule, so su root succeeds without a password. Dream measured the full chain at under 15 minutes.

Why does a firewall exploit reach identity systems?

Firewalls often hold LDAP connectivity, VPN authentication settings, and management server access. Once compromised, they become a bridge into Active Directory. In this campaign, the attacker used a management server that needed LDAP to authenticate VPN users as a launch point for domain attacks.

How can I tell if my firewall was compromised?

Look for unfamiliar small PHP files in web-accessible directories, any pam_permit.so entry in /etc/pam.d/su, and unexpected systemd units or rc.local entries that open reverse SSH tunnels. Also review LDAP and Active Directory logs on any management server for enumeration.

Is the PHP2Shell exploit chain only a problem for PHP 8.0.30?

No. Dream's artifacts include profiles for a 7.4.33 branch as well, though the full chain there was not calibrated. Version coverage was the attacker's main focus, so assume any version in the affected branches may be targeted until your vendor confirms otherwise.

Patch your firewall management interfaces this week, then pull the webserver and PAM files and check them for the artifacts above. Pass this to whoever owns your firewall management plane, because that's the team that can close the exposure fastest.