Writing

Writing2026

PHP2Shell (CVE-2026-109618 / CVE-2026-109619) Vulnerability Analysis & Technical Report

Contents
  1. 1. Executive Overview
  2. 1.1 Intuitive Analogy: System Architecture Perspective
  3. 1.2 Key Vulnerability Summary
  4. 2. Vulnerability Mechanics & Attack Pipeline
  5. 3. Deep Technical Analysis: Memory Management Defects
  6. 3.1 C-Level Pointer Uninitialization and longjmp() Emergency Unwinding
  7. 3.2 HTTP Multipart Manipulation & memory_limit Exhaustion Techniques
  8. 3.3 Web Server Worker Process Reuse & State Persistence
  9. 3.4 Heap Memory Re-allocation & Control Flow Hijacking
  10. 3.5 Memory Disclosure via Residual Data & Session Cookies
  11. 4. Threat Intelligence & Exploit Dynamics
  12. 4.1 Weaponization via Artificial Intelligence (LLM) & Automated Debugging
  13. 4.2 ASLR Mitigation & The 2-Stage Exploit Chain
  14. 5. Server Architecture Risk Matrix
  15. 6. Remediation & Mitigation
  16. 6.1 Permanent Solution (P0) - Apply Official Patches
  17. 6.2 Temporary Mitigations (P1)
  18. 7. Forensic & Detection Guide

1. Executive Overview

In October 2026, two critical security vulnerabilities were publicly disclosed in the PHP core engine, which powers approximately 70% of web systems worldwide. These flaws allow unauthenticated attackers to gain full control of targeted web servers or leak process memory without requiring any login or credential verification. This set of vulnerabilities has been dubbed ‘PHP2Shell’.

Regardless of the source code security of individual web applications (such as WordPress, Drupal, or Laravel), these vulnerabilities stem directly from memory management defects within the PHP engine itself.

1.1 Intuitive Analogy: System Architecture Perspective

To understand the flaw intuitively, imagine a website as an apartment building:

  • Standard Web Application Hacking: Picking the lock or breaking a window of an individual apartment unit.
  • PHP2Shell Attack: A structural flaw in the building’s core materials (the PHP engine itself), allowing attackers to bypass the front desk security or keypads entirely and gain direct control of the entire building management room.

1.2 Key Vulnerability Summary

Item Details
Vulnerability Identifiers CVE-2026-109618 (OOM Memory Corruption & Disclosure), CVE-2026-109619 (Stale Global State RCE)
Severity Critical (CVSS v4.0 Score: 9.2)
Attack Vector Unauthenticated Remote Code Execution (RCE), Memory Disclosure
Affected Versions PHP 5.4.0 through unpatched releases across all active branches (8.2, 8.3, 8.4, 8.5)
Patched Releases PHP 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 or higher

2. Vulnerability Mechanics & Attack Pipeline

The root cause of the PHP2Shell attack lies in a structural flaw where the PHP engine fails to properly clean up its state during fatal errors—specifically Out-Of-Memory (OOM) conditions—and abruptly performs an emergency stack unwind via longjmp().

The attack unfolds across a 3-stage pipeline:

  1. Stage 1: Inducing Intentional OOM (Out-Of-Memory)
    The attacker sends a specially crafted HTTP multipart (file upload) request that rapidly exhausts PHP’s allocated memory_limit.
  2. Stage 2: Emergency Abort & Residual Dangling Pointers (Triggering Use-After-Free)
    When OOM occurs, the PHP engine skips standard cleanup routines and terminates via longjmp(). While the active Heap memory is freed, global memory pointers are left uninitialized (Dangling Pointers).
  3. Stage 3: Memory Re-allocation & Server Hijacking via Secondary Request
    The attacker immediately issues a second HTTP request targeted at the same web server worker process. Malicious payload structures (fake function pointers) fill the newly allocated memory space, causing the server to reference the dangling pointer, execute malicious code, or leak sensitive memory data (passwords, API keys, etc.).

3. Deep Technical Analysis: Memory Management Defects

This section details the C-level memory management architecture and exploit mechanics within the PHP core engine.

3.1 C-Level Pointer Uninitialization and longjmp() Emergency Unwinding

Under normal execution, PHP frees allocated memory upon request completion and resets pointer addresses to NULL (0). However, when a memory allocation function (emalloc()) fails due to OOM, the PHP core immediately executes longjmp() to unwind the stack directly to the top-level error handler.

During this abrupt unwinding, cleanup routines inside core functions such as _zend_hash_str_add_or_update_i() are bypassed. Consequently, even though the OS and PHP allocator mark the Heap memory region as freed, global execution state objects (such as zend_executor_globals) retain dangling pointers pointing to the freed memory addresses.

3.2 HTTP Multipart Manipulation & memory_limit Exhaustion Techniques

To bypass the server’s post_max_size guard while triggering memory_limit exhaustion, attackers craft HTTP headers and body structures with the following traits:

  • Empty Filename Specification (filename=""): Generates metadata structures for PHP’s internal file upload management array (PG(http_post_files)) continuously without requiring actual file payloads.
  • Deeply Nested Field Names (a[b][c][d]...): Triggers the creation of multi-dimensional hash tables, fragmenting the Heap memory into numerous small chunks and accelerating exhaustion.
  • Chunked Transfer Encoding: Streams request data without specifying an initial content length, preventing web servers from pre-validating memory allocation thresholds.

3.3 Web Server Worker Process Reuse & State Persistence

Modern web hosting environments (such as Apache mod_php or PHP-FPM) keep worker processes alive across multiple requests to optimize performance.

Immediately after corrupting a worker process’s global state with the first request, the attacker uses HTTP/1.1 Keep-Alive or synchronized concurrent requests to ensure the second request hits the exact same worker process.

3.4 Heap Memory Re-allocation & Control Flow Hijacking

When the second request arrives at the corrupted worker, PHP’s memory manager (Zend MM) re-allocates the recently freed Heap chunk for the new request’s data.

The attacker structures the second request body with a fake virtual method table (VTable) and function pointers. When the PHP engine mistakenly trusts the dangling pointer from the prior request and invokes a method, execution branches to the attacker-controlled address (e.g., ROP gadget), achieving Remote Code Execution (RCE).

3.5 Memory Disclosure via Residual Data & Session Cookies

In CVE-2026-109618, the flaw leads not only to RCE but also to severe memory leaks:

  1. Triggering OOM during session initialization leaves the session ID pointer (PS(id)) pointing to freed Heap memory.
  2. When the second request arrives, the PHP engine treats whatever residual data remains in that memory space (such as database passwords, API keys, encryption tokens, or ASLR bypass addresses from previous operations) as a valid session ID string.
  3. PHP URL-encodes this raw memory content and returns it in the Set-Cookie: PHPSESSID=... response header, allowing attackers to decode and extract sensitive server secrets directly.

4. Threat Intelligence & Exploit Dynamics

4.1 Weaponization via Artificial Intelligence (LLM) & Automated Debugging

Although these flaws remained dormant in the PHP core for over a decade, security researchers (Wiz Research, Calif, etc.) leveraged advanced Large Language Models (LLMs) combined with automated debugging tools (GDB/LLVM) to compress what used to take months of manual research into a matter of hours.

4.2 ASLR Mitigation & The 2-Stage Exploit Chain

According to analysis by security expert Marcus Hutchins, most public proof-of-concept (PoC) scripts circulating online fail or simply crash the server. This is because modern operating systems enforce ASLR (Address Space Layout Randomization).

To achieve reliable exploitation, attackers must execute a 2-stage exploit chain:

  • [Stage 1] Memory Disclosure Attack: Exploit CVE-2026-109618 to extract process memory addresses and module base addresses via response cookies.
  • [Stage 2] ASLR Bypass & RCE Execution: Calculate exact ROP gadget offsets using the leaked addresses, then deliver the secondary payload to achieve stable code execution.

5. Server Architecture Risk Matrix

Server Environment Vulnerable? Risk Assessment & Vector
Apache + mod_php (prefork) Yes (Highest Risk) Unauthenticated RCE possible across any request path regardless of application code.
Apache + PHP-FPM Yes (High Risk) RCE possible via endpoints triggering session_start(), unserialize(), or upload handling.
Nginx + PHP-FPM Yes (High Risk) Same vector as Apache + PHP-FPM. Higher client_max_body_size increases exploitability.
FrankenPHP / LSAPI Yes (Caution) Similar to FPM worker reuse models, susceptible to state corruption.

6. Remediation & Mitigation

6.1 Permanent Solution (P0) - Apply Official Patches

Applying official vendor patches is the only complete solution to defend against all exploit variations.

  1. Immediately Upgrade PHP Core:
    • PHP 8.2 branch $\rightarrow$ 8.2.35 or higher
    • PHP 8.3 branch $\rightarrow$ 8.3.36 or higher
    • PHP 8.4 branch $\rightarrow$ 8.4.27 or higher
    • PHP 8.5 branch $\rightarrow$ 8.5.12 or higher
  2. Restart Web Services:
    • After updating binaries, run systemctl restart apache2 or systemctl restart php-fpm to flush corrupted worker instances from memory.

6.2 Temporary Mitigations (P1)

If immediate patching is not possible, implement these temporary measures to reduce exposure:

  • Update php.ini Settings:
    session.upload_progress.enabled = 0
    session.auto_start = 0
  • Web Application Firewall (WAF) Rules:
    • Block request bodies containing PHP_SESSION_UPLOAD_PROGRESS.
    • Drop requests containing empty filenames (filename="") combined with deeply nested fields (a[b][c][d]).

7. Forensic & Detection Guide

System administrators can check Linux server logs for signs of exploitation attempts using the following commands:

  1. Check for Pre-execution OOM Errors:
    grep -cE 'Allowed memory size of [0-9]+ bytes exhausted.*in Unknown on line 0' \
      /var/log/php_errors.log /var/log/apache2/error.log /var/log/httpd/error_log /var/log/php*-fpm.log
  2. Check for Worker Segmentation Faults:
    grep -E "Segmentation fault|signal 11|SIGSEGV" /var/log/apache2/error.log /var/log/php*-fpm.log
  3. Inspect Response Cookies for Memory Leaks:
    • Review web server or WAF logs for abnormally long or binary-encoded PHPSESSID cookie values in HTTP responses.