November 2, 2026
Exploiting PHP 8.4: From Out-of-Memory Conditions to Remote Code Execution (PHP2Shell)โ โ CWL
Introduction

By Sn1prex
6 min read
Introduction
In this lab, I explored a vulnerability in a PHP 8.4 application that demonstrates how improper memory handling can potentially lead to Remote Code Execution (RCE).
The challenge, provided by SecureCorps, involved exploiting weaknesses in multipart HTTP request parsing and session cleanup during Out-of-Memory (OOM) conditions.
The objective was to:
- Investigate the PHP application running on the target.
- Understand the OOM-related memory corruption.
- Obtain memory addresses to bypass ASLR.
- Achieve command execution as the web-server user .
- Retrieve a protected flag from the server.
This lab helped me understand how a memory-management issue can escalate into a serious application security compromise.
1. Initial Access and Environment Discovery
The first step was establishing SSH access to the target using the credentials provided by the lab.
After connecting, I verified my current user:
whoamiwhoamiThis confirmed that I had successfully accessed the target.
Attempting to access the flag
I initially attempted to read the flag directly:
cat /flag.txtcat /flag.txtHowever, the server returned:
Permission deniedPermission deniedI then Check the file permissions.
showed that the file was owned by:
root:www-dataroot:www-dataWith 640 permissions, only the owner and members of the assigned group could read it.
This established an important part of the challenge: the initial SSH user did not have sufficient permissions to access the flag, but the web-server account had the required group permissions.
2. Identifying the Web Server
Next, I Check the locally running web application.
curl -i http://127.0.0.1/index.phpcurl -i http://127.0.0.1/index.phpThe response confirmed that the application was accessible.
Environment identified from my actual terminal output:
ComponentVersion / DetailsOperating SystemDebian LinuxWeb ServerApache 2.4.69PHP RuntimePHP 8.4.26Applicationindex.phpInitial UserstudentWeb Server Userwww-data
One important observation: the actual Apache version in my environment was 2.4.69.
3. Understanding the Vulnerability
The central issue in this challenge involved PHP multipart request parsing and memory cleanup during Out-of-Memory conditions.
The lab's exploitation chain demonstrated several memory-management concepts.
3. 1Out-of-Memory (OOM)
What is it?
OOM happens when an application needs more memory than the system or its configured memory limit allows.
example:
Imagine opening too many applications on your computer. Your RAM becomes full, and when you open another application, the system struggles to allocate additional memory.
Similarly, when a PHP application processes a large HTTP request, it may run out of its allocated memory.
In this lab:
The exploit triggered an OOM condition during multipart request processing, exposing weaknesses in PHP's memory cleanup behavior.
3.2 Dangling Pointer / Use-After-Free (UAF)
What is it?
A dangling pointer is a reference to memory that has already been released. If a program continues using that reference, it can cause unexpected behavior.
example:
Imagine renting a locker:
- You rent locker number 25.
- You return the locker, and the management marks it as available.
- Another person rents the same locker.
- You still have an old key and try to access locker 25.
The key represents an outdated reference. The locker may now belong to someone else.
In this lab:
Improper cleanup during the OOM condition could leave stale references in PHP's internal structures. Accessing those references could lead to memory corruption.
3.3 Out-of-Bounds (OOB) Read
What is it?
An OOB read happens when a program reads data beyond the valid boundaries of an allocated memory region.
example:
Imagine a book has 100 pages, but someone tries to read page 105.
Page 105 is outside the book's valid range. In a computer program, an out-of-bounds read can expose data that the application was never supposed to access.
In this lab:
The exploit used a stale reference to access unintended memory and obtain information about internal memory addresses.
3.4 Memory Disclosure / Memory Leak
What is it?
Memory disclosure occurs when an application unintentionally exposes information stored in its memory.
Here, memory disclosure means revealing internal memory contents, not simply consuming RAM.
example:
Imagine a company accidentally exposing an internal document containing employee information, server details, or confidential records.
Similarly, a vulnerable application might unintentionally reveal internal memory addresses.
In this lab:
The exploit obtained memory information, including an address associated with PHP's internal library.
This information helped with the next stage of the exploitation chain.
3.5 ASLR (Address Space Layout Randomization) Bypass
What is ASLR?
ASLR is a security mechanism that randomly arranges important memory locations when a program starts.
Its purpose is to make it difficult for attackers to predict where specific functions or memory regions are located.
example:
Imagine a shopping mall where the locations of important offices change every day.
Someone trying to reach a particular office cannot simply memorize its previous location.
ASLR works similarly by making memory locations less predictable.
How can it be bypassed?
If a vulnerability exposes actual memory addresses, an attacker may use that information to reduce the uncertainty introduced by ASLR.
In this lab:
The memory disclosure stage provided addresses that the exploit used to calculate relevant PHP library and memory locations.
This helped overcome the protection offered by ASLR.
4. Locating and Understanding the Exploit
After identifying the application, I navigated to the provided exploit directory.
cd ~/exploit
ls -lacd ~/exploit
ls -laThe directory contained:
exploit.pyexploit.pyI inspected its available arguments using:
python3 exploit.py --helppython3 exploit.py --helpSome important parameters included:
--portSpecifies the application HTTP port
--workersConfigures Apache prefork worker handling
--cmdSpecifies the command used in the execution test
--proofSpecifies the proof-file location
--timeoutControls the operation timeout
--retriesConfigures the number of attempts
--outdirSpecifies the output directory
--restartAllows restarting a specified Docker container
The script implemented a multi-stage exploitation chain involving crafted HTTP requests, memory disclosure, address calculations, and memory corruption.
5. Exploitation and RCE Verification
The next objective was to verify whether the exploitation chain could achieve command execution.
I used the lab's benign identity-check command as the proof of execution.
During my first attempts, the exploit did not consistently complete the entire chain.
Some attempts failed because the expected memory disclosure was unavailable, while another attempt successfully obtained memory information but failed to produce the expected proof.
This demonstrated that obtaining a memory leak alone does not guarantee successful RCE.
Eventually, a subsequent attempt completed successfully.
Successful RCE verification
The terminal returned:
[4/4] RCE OK; proof /tmp/id9.txt:
uid=33(www-data) gid=33(www-data) groups=33(www-data)[4/4] RCE OK; proof /tmp/id9.txt:
uid=33(www-data) gid=33(www-data) groups=33(www-data)This was the most important evidence from the lab.
Let's understand the result:
uid=33(www-data): The command executed under the www-data user.gid=33(www-data): Its primary group was www-data.groups=33(www-data): The process belonged to the www-data group.
An important distinction is that my SSH session remained under the Same User account. The command executed through the vulnerable PHP application inherited the privileges of the web-server process.
Therefore, I did not need to manually log in as www-data.
After successfully verifying RCE as www-data, I completed the final objective of the challenge: retrieving the protected flag from /flag.txt.
The important concept here was the difference between the permissions of the original SSH user and the web-server process.
SSH login โ โ student
Running exploit.py โ โ student
Vulnerable PHP request โ โ Apache/PHP process
Exploited command โ โ www-data
Protected flag access โ โ www-data permissions
The flag was successfully retrieved.
6. Understanding the Exploitation Chain
The lab demonstrated the following conceptual sequence:
- OOM Trigger: Crafted multipart requests exercise the application's OOM-related cleanup behavior.
- Memory Disclosure: A stale-pointer read exposes memory information.
- ASLR Bypass: Disclosed addresses help identify relevant memory locations.
- Memory Corruption: The subsequent exploitation stage manipulates PHP internal structures.
- RCE: Execution is redirected to an unintended system command execution path.
- Privilege Context: The command executes with the privileges of the Apache/PHP worker, which is www-data.
The most interesting part was understanding how multiple memory-management weaknesses can combine into a much more serious security impact.
7. Why Did the Exploit Sometimes Fail?
One of the most interesting observations was that the exploit did not succeed consistently.
This behavior can be understood through several factors:
- ASLR: Memory addresses vary between processes.
- Heap Layout: Memory allocation and deallocation can change the arrangement of objects.
- Apache Worker Affinity: Requests need to reach the appropriate worker processes.
- Request Timing: The exploitation sequence depends on carefully coordinated HTTP requests.
- OOM Cleanup: Memory allocation and cleanup behavior can vary between attempts.
In my testing, the first attempts did not produce a successful proof. A later attempt completed the chain and confirmed RCE.
a successful memory leak does not automatically lead to code execution; it only provides useful information, while additional vulnerabilities and precise exploitation conditions are required to achieve Remote Code Execution (RCE).
8. Key Takeaways
This lab helped me understand the relationship between application-level vulnerabilities and operating-system privileges.
The most important concepts I learned were:
- How OOM conditions can affect memory cleanup.
- Why dangling pointers and use-after-free conditions are dangerous.
- How memory disclosure can weaken ASLR.
- Why exploitation chains depend on memory layout and request timing.
- How PHP application vulnerabilities can lead to RCE.
- Why web-server accounts should have restricted privileges.
- How Linux file permissions affect access to sensitive files.
The biggest takeaway for me was that a vulnerability in application memory management can have consequences far beyond application availability. Under the right conditions, it can potentially compromise the security boundary between an application and the underlying operating system.