Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
php2shell-deep-dive — In-depth technical walkthrough of PHP2Shell: chaining two PHP core CVEs from an out-of-memory crash and use-after-free into heap grooming, ASLR leaks, and remote code execution. | Kitploit
Tools/GitHubGitHub/djad04/php2shell-deep-dive
Memory ForensicsVulnerability AnalysisExploitationReverse EngineeringWeb Application ExploitationCTFPapers & ResearchLearning & EducationBinary Exploitation
GitHubdjad04/php2shell-deep-dive

php2shell-deep-dive

In-depth technical walkthrough of PHP2Shell: chaining two PHP core CVEs from an out-of-memory crash and use-after-free into heap grooming, ASLR leaks, and remote code execution.

634 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
View RepositoryWebsite

I started writing this research on October 26, 2026, and I'm not entirely sure when I'll finish it.

At the time of writing, there is still very little information available about PHP2Shell, particularly when it comes to detailed technical analysis of the vulnerabilities and the exploitation process.

Honestly, I was getting tired of finding explanations that only scratched the surface without actually showing what was happening internally. I wanted to do something different: a proper, in depth technical walkthrough that explores the entire process, examining every important detail and explaining not just WHAT happens, but WHY and HOW it happens.

This research is based on my own understanding of the PHP source code, my experiments, and the investigations I've conducted while trying to understand these vulnerabilities. I wanted to put all these pieces together, share my findings, and hopefully make some of the underlying concepts easier to understand for others.

One of my main goals was to make this accessible without sacrificing technical depth. I want someone with basic C knowledge and general programming experience to be able to follow along, even without any previous experience in low level memory exploitation.

I also hope this research can help clarify some of the things that are currently poorly explained or misunderstood. However, I want to be transparent: this is my own technical understanding of the vulnerabilities, not an official analysis or an infallible reference. I'm still learning, investigating, and connecting the dots myself. There may be mistakes, inaccuracies, or things I've misunderstood along the way.

If you notice something incorrect, have a different interpretation, or think something deserves further investigation, please don't hesitate to contact me. I'd genuinely appreciate corrections, discussions, and contributions that could help make this research more accurate and useful to everyone.

After all, the whole point of sharing this is to learn together and help more people understand what's actually happening under the hood.


Quick Navigation

Already familiar with the basics?? Jump straight to the part you care about:

  • Before we start: stack vs heap, memory allocation basics
  • How is This Dangerous?: the tale of the stale pointer, UAF reads and writes
  • The Stale Pointer: where it comes from:the UAF origin story inside PHP's session + OOM interaction
  • Building the attack request: the actual HTTP request that triggers the OOM
  • The Goal: what we need to leak and why (heap pointer + code pointer)
  • The Target Struct: zend_string: the struct PHP reads when building the session cookie
  • Reclaiming the Memory: Request #2 and the target zend_string struct
  • Heap Grooming Deep Dive: how we position forged data into the exact right memory slot
  • The multipart_buffer_read_body Mystery: the hidden allocation that almost broke my brain
  • Two Leaks Not One: why the heap leak and code leak need different calibrations
  • Code Leak (Stage 3): leaking a function pointer to defeat ASLR
  • Fingerprinting: how we know we got the right pointer
  • Parsing the Heap Leak: finding the chunk base in 256 bytes of chaos
  • The 1+8 Pipeline: how both leaks are actually delivered
  • Reusing the Allocator to Forge a Structure: the pDestructor hijack idea
  • The Trigger: PHP does the dirty work, real zend_hash_destroy code
  • Three Structures in One: ForgedArray + FakeExecuteData + FakeString in 384 bytes
  • Final Payload (Stage 4): forging a HashTable to hijack pDestructor and get RCE
  • The Primer Mechanism: how the freed primer's ghost in bucket[2] triggers the destruction chain
  • Command Output Trick: finding your own TCP socket in /proc
  • The Full Pipeline: all four stages end to end
  • Calibrating for a Different Build: how every number comes from heap analysis of a specific PHP build
  • Real World Friction: why this attack is way harder on a real production server
  • Steal My Bitcoin CTF: the challenge that started all this
  • Acknowledgements: credits and references

If you're new to heap exploitation or want the full experience, just keep scrolling. I wrote this to be read start to finish.


Before we start

There are a few things everyone should keep in mind before we dive in. They'll become particularly useful as we progress through the research. As I mentioned earlier, I want this walkthrough to be accessible to everyone, so I'll take the time to explain even the more fundamental concepts. If you're already familiar with them, feel free to skip ahead!

Stack vs. heap

In a typical program, memory is organized into different regions, including the stack and the heap.

For example, in C++:

int main() {
    int a = 30;       // Typically stored on the stack
    int* b = new int(30);  // b is typically on the stack,
                           // but the integer it points to is on the heap
}

Here, a is a local variable containing the value 30. The pointer b is also a local variable, but it contains the address of an integer allocated on the heap.

How memory allocation works

PHP is written mainly in C, so we have to understand how memory allocation works.

The OS provides a process with its own virtual address space. The process's memory allocator then manages allocations within the memory available to it.

For example, in C++, we have new, malloc(), and other ways to allocate memory.

Allocators often try to reuse freed memory instead of requesting new memory from the OS every time.

Also, when an object's lifetime ends, the data that was stored in its memory isn't necessarily erased immediately. That memory can simply be marked as available for reuse.


To better understand this, let's take a small look at the following code:

#include <cstdlib>
#include <iostream>

int main() {
    void* a = malloc(64);

    free(a);

    void* b = malloc(64);

    std::cout << a << "\n" << b << std::endl;

    free(b);
    return 0;
}

Here, when we print a and b, we may find that they contain the same numerical memory address.

Why? Because malloc() may reuse the memory previously allocated to a after we call free(a), avoiding the need to obtain another block of memory.

This isn't guaranteed to happen every time, but it's a common behavior.

Download Tool