Critical PHP Remote Code Execution Vulnerabilities Explained

•

 19 min video

•

 5 min read

YouTube video ID: cI8IquVEyVY

Source: YouTube video by Computerphile — Watch original video

PDF

The cybersecurity world experienced a significant storm recently, marked by the emergence of several vulnerabilities, most notably two critical PHP vulnerabilities that garnered widespread attention, even making headlines on major news outlets. These vulnerabilities allowed for remote code execution on affected servers, posing a severe risk to countless websites globally.

Understanding PHP

PHP, which stands for Hypertext Preprocessor, is a server-side scripting language widely used for web development. Unlike static HTML websites or client-side JavaScript, PHP enables the creation of dynamic websites that build themselves programmatically on the server. Developers embed PHP commands within HTML using a specific syntax (e.g., <?php ... ?>). When a server processes a PHP file, it executes these commands, allowing for dynamic content generation.

For instance, a video-sharing site could use PHP to query a database for a user's watched videos and then dynamically populate an HTML page with thumbnails and video titles, tailoring the content to the individual user. This programmatic approach makes PHP incredibly powerful for creating interactive and data-driven web applications. Its success is evident in its widespread adoption; a vast number of websites, including major platforms like WordPress and Wikipedia, rely on PHP.

The PHP Vulnerabilities

Last week, two significant PHP vulnerabilities were disclosed. The disclosure was somewhat chaotic, with details accidentally released on Hacker News and an exploit video prematurely published, forcing an accelerated public announcement. These vulnerabilities allowed an attacker to run arbitrary code on a server hosting a PHP website, a critical security flaw.

How the Vulnerabilities Work (General Terms)

PHP operates using "worker threads" that process incoming HTTP requests. Each worker thread maintains its own global state, including error states, objects in use, and extensions.

  1. Vulnerability 1: State Corruption Normally, when a request comes in, the worker thread processes it, generates the web page, and then cleans up temporary data associated with that request. However, under certain error conditions, the request might be destroyed, but the internal links or pointers within the worker thread's global state might not be properly reset. An attacker can exploit this by crafting an initial request that triggers this state corruption. Subsequent, carefully constructed requests can then leverage these lingering, incorrect pointers to inject and execute arbitrary code on the server.

  2. Vulnerability 2: Long Jump Misdirection This vulnerability is similar in principle. It exploits the long jump mechanism in C (which PHP uses), typically employed for error handling, such as out-of-memory errors. By triggering a specific error, an attacker can cause a long jump to occur. If the system's state isn't properly reset during this jump, and the attacker crafts their requests precisely, they can redirect the execution flow to their own malicious code on the server.

These vulnerabilities were particularly severe because they had existed for approximately 14 years across many PHP versions, from PHP 5 up to PHP 8.5, meaning a vast number of websites were potentially affected.

Demonstrating the Exploit

A practical demonstration showcased the severity of these vulnerabilities. The setup involved:

  • A PHP web server running a simple web page that returns "Okay" to a curl request.
  • An empty directory named "out" on the server.
  • A Python-based exploit (not custom-written for the demo, but sourced from a group called 9BIE) designed to leverage the vulnerabilities.

The exploit's goal was to run the id command on the server and write its output (the user ID of the web server process) into a file named P1 within the "out" directory.

Steps of the Demo:

  1. The PHP web server was started on port 1810.
  2. A curl request confirmed the server was operational, returning "Okay."
  3. The Python exploit was executed, targeting the PHP server.
  4. The exploit first "pinned" 150 worker threads. This is crucial because to successfully exploit the vulnerability, all malicious requests must be routed to the same worker thread. By tying up 149 other worker threads with useless tasks, the exploit ensured its requests would consistently hit the target thread.
  5. The exploit then made a series of carefully crafted requests to trigger the vulnerability.
  6. Upon successful execution, the exploit printed the output of the id command.
  7. Checking the "out" directory confirmed the creation of the P1 file, containing the www-data user ID, which is the standard user for web servers.

This demonstration unequivocally proved that these exploits are real and allow for arbitrary code execution on a remote server.

The Aftermath and Challenges

While the vulnerabilities are severe, exploiting them in the wild is not trivial.

  • Complexity of Exploitation: As seen in the demo, the exploit had to "pin" 150 worker threads to ensure its requests hit the correct target. In a live environment with many concurrent users, ensuring all malicious requests go to the same worker thread is significantly harder. A single legitimate request hitting the target thread at the wrong moment could disrupt the exploit.
  • Information Gathering: Successful exploitation often requires detailed knowledge of the target server's environment, including the specific PHP version, operating system, and even the C compiler used for compilation.
  • Responsible Disclosure Failure: The vulnerabilities were known to the PHP team as early as 2024, but they struggled to find a fix that didn't introduce other problems and couldn't determine a practical exploitation method at the time, leading them to defer a patch. This decision, in hindsight, was likely a mistake, especially with the rise of advanced testing tools like large language models (referred to as "stochastic parrots"). These models, potentially having ingested public discussions about the vulnerability, might have independently discovered or accelerated the discovery of working exploits.
  • Chaotic Release: The premature release of vulnerability details and exploit videos meant that the usual "responsible disclosure" process—where developers are informed, a patch is prepared, and then the vulnerability and patch are announced simultaneously—was bypassed. This forced an emergency patching effort.
  • Urgent Patching: Cybersecurity agencies worldwide, including the NCSC in the UK, issued urgent advisories, instructing organizations to patch their PHP installations immediately or take their websites offline. Despite the urgency, there hasn't been a widespread wave of "script kiddie" attacks, possibly due to the rapid patching efforts or the inherent difficulty of exploiting these vulnerabilities in a real-world, high-traffic environment.

The incident highlights the ongoing challenges in cybersecurity, from the complexities of finding and fixing deep-seated bugs in widely used software to the difficulties of managing vulnerability disclosures in an increasingly interconnected and AI-driven world.

  Takeaways

  • Two critical PHP vulnerabilities affecting versions 5 through 8.5 allowed remote code execution by corrupting worker thread state or misdirecting long jumps, posing a severe risk to countless websites.
  • The exploits required precise control of PHP worker threads, such as pinning 150 threads, which makes real‑world attacks difficult despite the vulnerabilities’ severity.
  • Chaotic, premature disclosure of the bugs forced an emergency patch and highlighted shortcomings in the responsible disclosure process for high‑impact software flaws.
  • Large language models may have accelerated exploit development by ingesting public discussions about the vulnerabilities, illustrating new AI‑related security challenges.
  • Global cybersecurity agencies urged immediate patching, and although the flaws were serious, widespread script‑kiddie attacks have not materialized due to the exploitation complexity.

Frequently Asked Questions

How does the "state corruption" vulnerability enable arbitrary code execution in PHP?

The state‑corruption flaw occurs when a PHP request is destroyed under certain error conditions but the worker thread’s global pointers are not reset, leaving dangling references. An attacker can send a crafted initial request to create the corrupted state and then follow up with specially designed requests that reuse those stale pointers, causing the server to execute the attacker’s code.

Why does the exploit need to pin 150 worker threads to succeed?

The exploit pins 150 PHP worker threads so that all malicious requests are forced onto the same thread that holds the corrupted state. By occupying the other 149 threads with harmless tasks, the attacker guarantees that subsequent crafted requests hit the targeted thread, which is essential because the vulnerability only works when the same thread processes the sequence of requests.

Who is Computerphile on YouTube?

Computerphile is a YouTube channel that publishes videos on a range of topics. Browse more summaries from this channel below.

Does this page include the full transcript of the video?

Yes, the full transcript for this video is available on this page. Click 'Show transcript' in the sidebar to read it.

How the Vulnerabilities Work (General Terms)

PHP operates using "worker threads" that process incoming HTTP requests. Each worker thread maintains its own global state, including error states, objects in use, and extensions. 1. **Vulnerability 1: State Corruption** Normally, when a request comes in, the worker thread processes it, generates the web page, and then cleans up temporary data associated with that request. However, under certain error conditions, the request might be destroyed, but the internal links or pointers within the worker thread's global state might not be properly reset. An attacker can exploit this by crafting an initial request that triggers this state corruption. Subsequent, carefully constructed requests can then leverage these lingering, incorrect pointers to inject and execute arbitrary code on the server. 2. **Vulnerability 2: Long Jump Misdirection** This vulnerability is similar in principle. It exploits the `long jump` mechanism in C (which PHP uses), typically employed for error handling, such as out-of-memory errors. By triggering a specific error, an attacker can cause a `long jump` to occur. If the system's state isn't properly reset during this jump, and the attacker crafts their requests precisely, they can redirect the execution flow to their own malicious code on the server. These vulnerabilities were particularly severe because they had existed for approximately 14 years across many PHP versions, from PHP 5 up to PHP 8.5, meaning a vast number of websites were potentially affected.

Helpful resources related to this video

If you want to practice or explore the concepts discussed in the video, these commonly used tools may help.

Links may be affiliate links. We only include resources that are genuinely relevant to the topic.

Full transcript is not shown on this page

This page focuses on the summary and original notes. For full verification, refer to the original YouTube video.

PDF