<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged rce</title>
<link>https://coderlegion.com/tag/rce</link>
<description>Powered by Question2Answer</description>
<item>
<title>PHP2Shell: When a Simple Upload Feature Turns Into Remote Code Execution</title>
<link>https://coderlegion.com/33222/php2shell-when-a-simple-upload-feature-turns-into-remote-code-execution</link>
<description>&lt;p&gt;&lt;em&gt;Exploring CVE-2026-109618 and CVE-2026-109619 through a TryHackMe lab.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;October is Cybersecurity Awareness Month, and honestly, this month has been quite interesting from a cybersecurity perspective. There have been plenty of vulnerabilities, attacks and security incidents worth paying attention to.&lt;/p&gt;
&lt;p&gt;But while going through TryHackMe, something particularly caught my attention: &lt;strong&gt;PHP2Shell&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;At first, I was interested in the upload exploitation technique. I mean, how does something as ordinary as a file upload eventually lead to remote code execution?&lt;/p&gt;
&lt;p&gt;That question made me curious enough to investigate further.&lt;/p&gt;
&lt;p&gt;On October 21, 2026, two critical vulnerabilities were disclosed in PHP: &lt;strong&gt;CVE-2026-109618&lt;/strong&gt; and &lt;strong&gt;CVE-2026-109619&lt;/strong&gt;. Together, they demonstrated how an unauthenticated attacker could potentially execute operating system commands on a vulnerable PHP server through specially crafted HTTP requests.&lt;/p&gt;
&lt;p&gt;And here's the part I found most interesting:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The application itself didn't even need to be vulnerable.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The weakness existed inside PHP's runtime, meaning that even an application with perfectly ordinary PHP code could potentially be affected.&lt;/p&gt;
&lt;p&gt;So, I decided to explore the vulnerability through a TryHackMe lab and understand what was actually happening behind the scenes.&lt;/p&gt;
&lt;p&gt;Let's break it down.&lt;/p&gt;
&lt;h3 id=&quot;1-first-what-exactly-is-php2shell-&quot;&gt;1. First, what exactly is PHP2Shell?&lt;/h3&gt;
&lt;p&gt;PHP2Shell is the name given to a pair of vulnerabilities affecting the PHP runtime.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;CVE      &lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;CVE-2026-109618  &lt;/td&gt;&lt;td&gt;Memory disclosure&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;CVE-2026-109619 &lt;/td&gt;&lt;td&gt;Remote code execution&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Both vulnerabilities received a CVSS v4.0 score of 9.2 (Critical).&lt;/p&gt;
&lt;p&gt;The vulnerabilities involve PHP's internal request-processing and memory-management mechanisms.&lt;/p&gt;
&lt;p&gt;What makes this particularly concerning is that the vulnerable code isn't necessarily part of the application developers write. It exists deeper inside the PHP engine.&lt;/p&gt;
&lt;p&gt;So, updating your WordPress installation or fixing your Laravel application wouldn't automatically resolve the underlying problem.&lt;/p&gt;
&lt;p&gt;To understand why, I first needed to understand the PHP feature involved in the exploitation.&lt;/p&gt;
&lt;h3 id=&quot;2-the-interesting-part-php-upload-progress&quot;&gt;2. The interesting part: PHP Upload Progress&lt;/h3&gt;
&lt;p&gt;Every vulnerability has an underlying condition that makes exploitation possible. In this case, that condition involves a feature called session.upload_progress.&lt;/p&gt;
&lt;p&gt;PHP provides this feature to track file uploads.&lt;/p&gt;
&lt;p&gt;Imagine uploading a large file through a website. You might see a progress indicator showing how much of the file has been uploaded.&lt;/p&gt;
&lt;p&gt;PHP can help provide this information by tracking details such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Uploaded file name.&lt;/li&gt;
&lt;li&gt;Total upload size.&lt;/li&gt;
&lt;li&gt;Amount of data received.&lt;/li&gt;
&lt;li&gt;Current upload progress.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The relevant configuration directive is:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;session.upload_progress.enabled = On&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And the default form field responsible for activating this functionality is:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PHP_SESSION_UPLOAD_PROGRESS&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now, here's where things get interesting.&lt;/p&gt;
&lt;p&gt;PHP processes this upload-progress information while parsing an incoming multipart/form-data request.&lt;/p&gt;
&lt;p&gt;That happens before the application script actually starts executing.&lt;/p&gt;
&lt;p&gt;In simpler terms, PHP is already processing the upload before the website's own PHP code gets control.&lt;/p&gt;
&lt;p&gt;This means the vulnerable functionality can be reached without the target page necessarily implementing its own file-upload feature.&lt;/p&gt;
&lt;p&gt;I found this particularly interesting because it changes how we think about the attack surface.&lt;/p&gt;
&lt;p&gt;We normally think about vulnerabilities in terms of application code, authentication systems and user input validation.&lt;/p&gt;
&lt;h3 id=&quot;3-understanding-the-actual-memory-management-bug&quot;&gt;3. Understanding the actual memory-management bug&lt;/h3&gt;
&lt;p&gt;This was probably the part that required the most attention from me.&lt;/p&gt;
&lt;p&gt;To understand PHP2Shell, I needed to understand what happens when PHP runs out of memory.&lt;/p&gt;
&lt;p&gt;PHP has a configuration directive called memory_limit, which restricts how much memory a request can consume.&lt;/p&gt;
&lt;p&gt;When a request exceeds that limit, PHP can trigger something called a bailout.&lt;/p&gt;
&lt;p&gt;Internally, the engine uses longjmp() to escape the current execution path after a fatal error.&lt;/p&gt;
&lt;p&gt;Normally, software should clean up its resources properly when an operation finishes.&lt;/p&gt;
&lt;p&gt;However, an emergency bailout can interrupt that cleanup process.&lt;/p&gt;
&lt;p&gt;This is where PHP2Shell becomes interesting.&lt;/p&gt;
&lt;p&gt;Consider a situation where PHP frees a memory block but doesn't properly clear the pointer referencing it before the bailout occurs.&lt;/p&gt;
&lt;p&gt;That pointer can remain behind even though the memory it references is no longer valid.&lt;/p&gt;
&lt;p&gt;This is known as a dangling pointer.&lt;/p&gt;
&lt;p&gt;In this case, the vulnerability is associated with CWE-824.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why is a dangling pointer dangerous?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Think of memory as a collection of storage locations.&lt;/p&gt;
&lt;p&gt;A program allocates a location, stores information there and keeps a pointer to access it later.&lt;/p&gt;
&lt;p&gt;Now imagine that the location gets freed, but the program still has the old pointer.&lt;/p&gt;
&lt;p&gt;Another allocation might eventually reuse that same memory location.&lt;/p&gt;
&lt;p&gt;The original pointer now references something different from what it was supposed to reference.&lt;/p&gt;
&lt;p&gt;That's the fundamental problem behind a use-after-free scenario.&lt;/p&gt;
&lt;p&gt;But PHP2Shell has another interesting component.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Apache worker connection&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The lab uses Apache with mod_php in a prefork configuration.&lt;/p&gt;
&lt;p&gt;In this setup, an Apache worker can process multiple requests during its lifetime.&lt;/p&gt;
&lt;p&gt;That means memory state left behind by one request can potentially affect a subsequent request handled by the same worker.&lt;/p&gt;
&lt;p&gt;So, the issue isn't simply that PHP encounters an error.&lt;/p&gt;
&lt;p&gt;The problem is that the memory state can survive long enough to influence what happens next.&lt;/p&gt;
&lt;p&gt;And this is what makes the exploitation chain possible.&lt;/p&gt;
&lt;h3 id=&quot;4-understanding-the-two-vulnerabilities&quot;&gt;4. Understanding the two vulnerabilities&lt;/h3&gt;
&lt;p&gt;Now that we understand the memory-management problem, let's look at how the two CVEs fit together.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CVE-2026-109618: Memory Disclosure&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The first vulnerability allows an attacker to retrieve information from the PHP worker's memory.&lt;/p&gt;
&lt;p&gt;The exploitation involves manipulating the stale session-related pointer and the length of the string PHP subsequently processes.&lt;/p&gt;
&lt;p&gt;The interesting part is where this information gets returned.&lt;/p&gt;
&lt;p&gt;PHP uses the following HTTP response header:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Set-Cookie: PHPSESSID&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The resulting oversized session identifier can expose adjacent process memory.&lt;/p&gt;
&lt;p&gt;That memory may contain useful information, including heap and library addresses.&lt;/p&gt;
&lt;p&gt;Why does that matter?&lt;/p&gt;
&lt;p&gt;Because modern operating systems use a security mechanism called Address Space Layout Randomization (ASLR).&lt;/p&gt;
&lt;p&gt;ASLR randomizes memory locations to make exploitation more difficult.&lt;/p&gt;
&lt;p&gt;An attacker generally needs to know where important functions and memory regions are located to reliably manipulate execution.&lt;/p&gt;
&lt;p&gt;The memory disclosure vulnerability helps reveal those addresses.&lt;/p&gt;
&lt;p&gt;In the TryHackMe lab, the exploitation chain obtains two important addresses:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The PHP heap base address.&lt;/li&gt;
&lt;li&gt;The libphp base address.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This information becomes useful in the next stage.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CVE-2026-109619: Remote Code Execution&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is where things get considerably more serious.&lt;/p&gt;
&lt;p&gt;The second vulnerability takes the memory manipulation further.&lt;/p&gt;
&lt;p&gt;The exploitation chain uses a forged internal PHP structure called a HashTable.&lt;/p&gt;
&lt;p&gt;One of the important fields involved is:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pDestructor&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This field is associated with the function PHP calls when destroying certain values.&lt;/p&gt;
&lt;p&gt;The researchers demonstrated how manipulating this structure could redirect the cleanup process toward the system() function inside PHP's library.&lt;/p&gt;
&lt;p&gt;Instead of executing the expected cleanup operation, PHP ends up invoking a function capable of executing operating-system commands.&lt;/p&gt;
&lt;p&gt;And that's how the memory corruption can ultimately become remote code execution.&lt;/p&gt;
&lt;p&gt;What I found particularly interesting is that the normal cleanup process itself becomes part of the exploitation chain.&lt;/p&gt;
&lt;p&gt;Something designed to manage resources properly can become dangerous when the underlying memory state has been corrupted.&lt;/p&gt;
&lt;h3 id=&quot;5-my-practical-investigation-on-tryhackme&quot;&gt;5. My practical investigation on TryHackMe&lt;/h3&gt;
&lt;p&gt;After understanding the concepts, I moved on to the practical investigation.&lt;/p&gt;
&lt;p&gt;The TryHackMe room provided a vulnerable PHP server running inside a Docker container.&lt;/p&gt;
&lt;p&gt;I connected to the machine using SSH with the provided credentials.&lt;/p&gt;
&lt;p&gt;The first thing I wanted to do was identify the running container and check its PHP version.&lt;/p&gt;
&lt;p&gt;I used:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker ps --format '{{.Names}}  {{.Image}}  {{.Status}}'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The output showed:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;php2shell-target  php:8.4.26-apache  Up&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Next, I checked the PHP version inside the container:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker exec php2shell-target php -v&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The target was running:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PHP 8.4.26
Zend Engine v4.4.26&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This was important because PHP 8.4.27 was the fixed release.&lt;/p&gt;
&lt;p&gt;So, the lab environment was running a vulnerable version.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inspecting the application&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Next, I wanted to see what the actual website was returning.&lt;/p&gt;
&lt;p&gt;I executed:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;curl -s http://127.0.0.1:8088/index.php&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The response?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;OK&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That's it.&lt;/p&gt;
&lt;p&gt;I also inspected the PHP file:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker exec php2shell-target cat /var/www/html/index.php&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And found:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;?php echo &quot;OK\n&quot;; ?&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;At this point, I found the situation particularly interesting.&lt;/p&gt;
&lt;p&gt;There was no login system.&lt;/p&gt;
&lt;p&gt;There was no database.&lt;/p&gt;
&lt;p&gt;There was no application-level file-upload functionality.&lt;/p&gt;
&lt;p&gt;The application was literally printing OK.&lt;/p&gt;
&lt;p&gt;Yet the underlying PHP runtime was vulnerable.&lt;/p&gt;
&lt;p&gt;This reinforced one of the biggest lessons from the room: an application doesn't necessarily need to contain vulnerable code for its underlying server to be exploitable.&lt;/p&gt;
&lt;h3 id=&quot;6-observing-the-memory-disclosure&quot;&gt;6. Observing the memory disclosure&lt;/h3&gt;
&lt;p&gt;After confirming the target environment, I moved to the memory-disclosure stage.&lt;/p&gt;
&lt;p&gt;The lab provided an existing exploit repository:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;php2shell-bypass-aslr-exp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I navigated into the directory:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cd ~/php2shell-bypass-aslr-exp&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The provided exploit handled the exploitation stages.&lt;/p&gt;
&lt;p&gt;I ran it against the local target:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python3 exploit.py -u http://127.0.0.1:8088/index.php&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The output showed two particularly interesting stages:&lt;/p&gt;
&lt;p&gt;`[*] stage 1: heap leak&lt;br&gt;
[+] chunk base = 0x...&lt;/p&gt;
&lt;p&gt;[*] stage 2: libphp leak&lt;br&gt;
[+] libphp base = 0x...`&lt;/p&gt;
&lt;p&gt;These were the two memory addresses the exploitation chain needed.&lt;/p&gt;
&lt;p&gt;The first revealed the heap location, while the second revealed the PHP library's base address.&lt;/p&gt;
&lt;p&gt;I found this interesting because ASLR is specifically designed to make these locations unpredictable.&lt;/p&gt;
&lt;p&gt;Instead of simply guessing the addresses, the exploitation chain obtains information about the actual memory layout.&lt;/p&gt;
&lt;p&gt;This demonstrated how a memory disclosure vulnerability can become a stepping stone toward something much more serious.&lt;/p&gt;
&lt;h3 id=&quot;7-from-memory-disclosure-to-remote-code-execution&quot;&gt;7. From memory disclosure to remote code execution&lt;/h3&gt;
&lt;p&gt;Now came the part I was particularly interested in: actually demonstrating command execution.&lt;/p&gt;
&lt;p&gt;After the memory disclosure stages, the exploit proceeded to the final stage involving the manipulated HashTable structure.&lt;/p&gt;
&lt;p&gt;The lab provided the following execution proof:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PROOF: uid=33(www-data) gid=33(www-data) groups=33(www-data)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And there it was.&lt;/p&gt;
&lt;p&gt;The command had executed successfully under the www-data account, which is commonly used by web servers on Linux systems.&lt;/p&gt;
&lt;p&gt;This confirmed that the exploitation chain had achieved remote code execution in the lab environment.&lt;/p&gt;
&lt;p&gt;The next step was retrieving the flag.&lt;/p&gt;
&lt;p&gt;The lab's exploit used the following command:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;python3 exploit.py \
-u http://127.0.0.1:8088/index.php \
-c 'cat /f&amp;gt;/out/p1' \
--proof-file out/p1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The result returned the flag:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;THM{b4ilout_l3aves_th3_h3ap_dang1ing}&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;div&gt;
**THM{b4ilout_l3aves_th3_h3ap_dang1ing}**

A pretty fitting flag for a vulnerability involving a bailout and a dangling pointer.

&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;What made this practical exercise memorable for me was the fact that the target application itself never changed.&lt;/p&gt;
&lt;p&gt;It continued to be a simple PHP page returning OK.&lt;/p&gt;
&lt;p&gt;The exploitation happened because of the vulnerable runtime underneath it.&lt;/p&gt;
&lt;h3 id=&quot;8-detection-and-mitigation&quot;&gt;8. Detection and mitigation&lt;/h3&gt;
&lt;p&gt;Understanding how an attack works is one thing.&lt;/p&gt;
&lt;p&gt;Knowing how to prevent or detect it is equally important.&lt;/p&gt;
&lt;p&gt;Since PHP2Shell affects the PHP runtime, updating the application alone isn't enough.&lt;/p&gt;
&lt;p&gt;The PHP installation itself needs to be patched.&lt;/p&gt;
&lt;p&gt;The fixed releases identified in the security advisory are:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;PHP branch &lt;/th&gt;&lt;th&gt;Fixed release&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;PHP 8.5 &lt;/td&gt;&lt;td&gt;8.5.12&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;PHP 8.4 &lt;/td&gt;&lt;td&gt;8.4.27&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;PHP 8.3 &lt;/td&gt;&lt;td&gt;8.3.36&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;PHP 8.2 &lt;/td&gt;&lt;td&gt;8.2.35&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Temporary mitigation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If immediate patching isn't possible, disabling the upload-progress functionality can reduce exposure to the relevant attack path:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;session.upload_progress.enabled = 0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;However, this should be treated as a temporary mitigation rather than a permanent solution.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What should defenders monitor?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Some suspicious indicators worth investigating include:&lt;/li&gt;
&lt;li&gt;Unusually large PHPSESSID values in Set-Cookie response headers.&lt;/li&gt;
&lt;li&gt;Suspicious multipart POST requests.&lt;/li&gt;
&lt;li&gt;Unexpected PHP worker crashes.&lt;/li&gt;
&lt;li&gt;Memory exhaustion errors.&lt;/li&gt;
&lt;li&gt;PHP processes unexpectedly spawning shell processes.&lt;/li&gt;
&lt;li&gt;Unusual command execution under the web server account.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One important lesson here is that monitoring only the application layer isn't sufficient.&lt;/p&gt;
&lt;p&gt;Because the vulnerability is triggered during PHP's internal request processing, detection and prevention need to account for activity happening before the application script executes.&lt;/p&gt;
&lt;p&gt;Patching the runtime remains the priority.&lt;/p&gt;
&lt;h3 id=&quot;9-what-i-learned-from-this-investigation&quot;&gt;9. What I learned from this investigation&lt;/h3&gt;
&lt;p&gt;This was more than just another TryHackMe room for me.&lt;/p&gt;
&lt;p&gt;It helped me connect several concepts that I had previously encountered separately.&lt;/p&gt;
&lt;p&gt;Some of the things I explored included:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How PHP processes multipart/form-data requests.&lt;/li&gt;
&lt;li&gt;What session.upload_progress actually does.&lt;/li&gt;
&lt;li&gt;How memory allocation and dangling pointers work.&lt;/li&gt;
&lt;li&gt;Why an out-of-memory bailout can become dangerous.&lt;/li&gt;
&lt;li&gt;What ASLR does and why attackers try to bypass it.&lt;/li&gt;
&lt;li&gt;How memory disclosure can assist remote code execution.&lt;/li&gt;
&lt;li&gt;How PHP's internal cleanup mechanisms can become part of an exploitation chain.&lt;/li&gt;
&lt;li&gt;Why securing the application doesn't necessarily secure the runtime.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But there's one thing that stood out above everything else.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sometimes, the vulnerability isn't in the code you wrote. It's in the code your code depends on.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As someone learning cybersecurity alongside software development and AI/ML, I find these investigations particularly valuable.&lt;/p&gt;
&lt;p&gt;I don't want to simply learn which command executes an exploit or how to retrieve a flag.&lt;/p&gt;
&lt;p&gt;I want to understand what happens underneath, why a vulnerability exists, how it can be abused and, most importantly, how defenders can prevent it.&lt;/p&gt;
&lt;p&gt;Because there's a difference between knowing that something works and understanding why it works.&lt;/p&gt;
&lt;p&gt;And I'm genuinely enjoying the process of learning that difference.&lt;/p&gt;
&lt;h3 id=&quot;final-thoughts&quot;&gt;Final thoughts&lt;/h3&gt;
&lt;p&gt;PHP2Shell was a great reminder that cybersecurity isn't just about finding vulnerabilities in websites.&lt;/p&gt;
&lt;p&gt;It's also about understanding the technologies, runtimes, libraries and systems that make those websites work in the first place.&lt;/p&gt;
&lt;p&gt;A seemingly harmless upload-progress feature, combined with a memory-management failure, demonstrated how something deep inside a runtime could eventually lead to remote code execution.&lt;/p&gt;
&lt;p&gt;And that's what makes cybersecurity so interesting to me.&lt;/p&gt;
&lt;p&gt;There's always another layer to investigate, another question to ask and another mechanism to understand.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stay curious. Keep learning. Keep breaking things in controlled environments, and most importantly, understand what you're doing.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: This investigation was conducted in an authorized TryHackMe lab environment. The exploit and command-execution results described above relate to that controlled environment.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/33222/php2shell-when-a-simple-upload-feature-turns-into-remote-code-execution</guid>
<pubDate>Sat, 31 Oct 2026 12:16:03 +0000</pubDate>
</item>
</channel>
</rss>