{"id":191,"date":"2026-10-27T10:46:03","date_gmt":"2026-10-27T09:46:03","guid":{"rendered":"https:\/\/hoja.in\/blog\/?p=191"},"modified":"2026-10-27T10:46:03","modified_gmt":"2026-10-27T09:46:03","slug":"php2shell-check-your-servers-with-a-few-shell-scripts","status":"publish","type":"post","link":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/","title":{"rendered":"PHP2Shell: check your servers with a few shell scripts"},"content":{"rendered":"<p>Hi folks,<\/p>\n<p>Last week a video from Hood Informatik landed in my feed: <a href=\"https:\/\/www.youtube.com\/watch?v=qXv8NAIFm9o\">PHP2Shell: Wie ein Speicherfehler zur Shell wird<\/a> (German). The title made me stop scrolling. Not a bug in some plugin, not a bug in TYPO3 or WordPress, but two critical bugs in the PHP interpreter itself. Anybody who sends a crafted request can run code on the server, without a login, and on Apache with mod_php even before your application sees the request.<\/p>\n<p>My first thought was the usual one: does this concern me? I look after TYPO3 sites, my own site and this blog run on PHP, so yes, it does. Here is what I understood from the advisory and the research write-ups, and the small shell scripts I now use to check servers. Everything below is defensive. No exploit code, only checks.<\/p>\n<h2>What PHP2Shell is<\/h2>\n<p>PHP2Shell is the name for <strong>CVE-2026-109618<\/strong> and <strong>CVE-2026-109619<\/strong>, both rated CVSS 9.2. They were found by Calif together with researchers from OpenAI and Wiz, reported to the PHP security team in August, and fixed in the security release of 21 October 2026. watchTowr reports attacks since the day of the release, and CISA has added CVE-2026-109618 to its catalogue of exploited vulnerabilities. So this is not a &#8220;patch it next month&#8221; thing.<\/p>\n<p>The fixed versions are:<\/p>\n<table>\n<thead>\n<tr>\n<th>Branch<\/th>\n<th>Fixed in<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>8.5<\/td>\n<td>8.5.12<\/td>\n<\/tr>\n<tr>\n<td>8.4<\/td>\n<td>8.4.27<\/td>\n<\/tr>\n<tr>\n<td>8.3<\/td>\n<td>8.3.36<\/td>\n<\/tr>\n<tr>\n<td>8.2<\/td>\n<td>8.2.35<\/td>\n<\/tr>\n<tr>\n<td>8.1, 8.0, 7.4<\/td>\n<td>only vendor or distribution backports<\/td>\n<\/tr>\n<tr>\n<td>7.3 and older<\/td>\n<td>no fix, upgrade the branch<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Affected are all PHP setups that serve web requests: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. The PHP team sees the highest risk with mod_php.<\/p>\n<h2>Why a memory error becomes a shell<\/h2>\n<p>This part I found really interesting. When PHP hits <code>memory_limit<\/code>, it stops with a fatal error right where it is. Normally that is fine, the request dies and the next one starts clean. But some places in the engine do their work in two steps. For example, a hash table first counts a new element and only then writes it. If the memory runs out exactly between those two steps, the cleanup later trusts the counter and works with something that was never finished.<\/p>\n<p>Think of a waiter who is called away while laying a table. The manager sees &#8220;table 4 is ready&#8221; on the list and seats the next guest. Now add that PHP workers serve many requests one after another. Some of this half-finished state survives into the next request on the same worker, pointing at memory that was already freed. An attacker who controls what lands in that memory has a write primitive, and from there it goes to code execution.<\/p>\n<p>How do you make PHP run out of memory at exactly the right moment? With a multipart upload that has lots of empty parts and deeply nested field names, sent in a way that skips the <code>post_max_size<\/code> check. PHP parses all of that during request startup. Your <code>index.php<\/code> has not even started yet. That is why updating TYPO3, WordPress or any plugin does not help here. The runtime itself needs the update.<\/p>\n<p>You can see the basic effect on your own machine. This script is harmless, it only shows that a fatal out-of-memory error stops PHP in the middle of a job while shutdown code still runs with the unfinished state:<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\/\/ A fatal \"Allowed memory size exhausted\" stops PHP in the middle of whatever it is doing.\n\/\/ Shutdown functions still run afterwards - with state that was never finished.\n$state = ['step' =&gt; 'started'];\n\nregister_shutdown_function(static function () use (&amp;$state): void {\n    echo PHP_EOL, 'shutdown sees: ', json_encode($state), PHP_EOL;\n});\n\n$state['step'] = 'building a big array';\n$rows = [];\nwhile (true) {\n    $rows[] = str_repeat('x', 1024);\n}\n$state['step'] = 'done'; \/\/ never reached<\/code><\/pre>\n<pre><code class=\"language-bash\">php -d memory_limit=8M oom-demo.php<\/code><\/pre>\n<pre><code class=\"language-text\">Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 20480 bytes) in oom-demo.php on line 13\n\nshutdown sees: {\"step\":\"building a big array\"}<\/code><\/pre>\n<p>In userland this is just an annoying half-done job. Inside the engine, in C, the same pattern ends with a dangling pointer. That is the whole story in one sentence.<\/p>\n<h2>Step 1: Check every PHP binary on the machine<\/h2>\n<p>Most servers have more than one PHP. My shared hosting has PHP 8.0 to 8.5 installed side by side, a Debian box has <code>php8.3<\/code> and <code>php8.4<\/code>, and so on. This script asks each binary for its version and compares it with the fixed release of its branch:<\/p>\n<pre><code class=\"language-bash\">#!\/usr\/bin\/env bash\n# Check every PHP binary on this machine against the PHP2Shell fix versions\n# (CVE-2026-109618 \/ CVE-2026-109619, PHP security release of 21 Oct 2026).\nset -u\n\nfixed_for() {\n  case \"$1\" in\n    8.5) echo 8.5.12 ;;\n    8.4) echo 8.4.27 ;;\n    8.3) echo 8.3.36 ;;\n    8.2) echo 8.2.35 ;;\n    *)   echo none ;;\n  esac\n}\n\nfor bin in $(ls \/usr\/bin\/php[0-9]* \/usr\/local\/bin\/php \/usr\/bin\/php \/opt\/cpanel\/ea-php*\/root\/usr\/bin\/php 2&gt;\/dev\/null | sort -u); do\n  version=$(\"$bin\" -r 'echo PHP_VERSION;' 2&gt;\/dev\/null) || continue\n  branch=${version%.*}\n  fixed=$(fixed_for \"$branch\")\n  if [ \"$fixed\" = none ]; then\n    status=\"NO FIX - upgrade the branch (or use a vendor backport)\"\n  elif \"$bin\" -r \"exit(version_compare(PHP_VERSION, '$fixed', '&gt;=') ? 0 : 1);\"; then\n    status=\"ok (fixed in $fixed)\"\n  else\n    status=\"VULNERABLE - update to $fixed\"\n  fi\n  printf '%-40s %-8s %sn' \"$bin\" \"$version\" \"$status\"\ndone<\/code><\/pre>\n<p>I ran it inside my DDEV project first, and honestly I was a bit surprised:<\/p>\n<pre><code class=\"language-text\">\/usr\/bin\/php                             8.4.17   VULNERABLE - update to 8.4.27\n\/usr\/bin\/php8.2                          8.2.30   VULNERABLE - update to 8.2.35\n\/usr\/bin\/php8.3                          8.3.30   VULNERABLE - update to 8.3.36\n\/usr\/bin\/php8.4                          8.4.17   VULNERABLE - update to 8.4.27\n\/usr\/bin\/php8.5                          8.5.2    VULNERABLE - update to 8.5.12<\/code><\/pre>\n<p>A local DDEV is not reachable from the internet, so this is not a fire. But it is a good reminder that container images have their own PHP and need their own update. On the hosting the command line binaries already showed 8.4.27 and 8.3.36, built one day before the release. The PHP team shared the patches with distributions and vendors in advance, and here it paid off.<\/p>\n<h2>Step 2: Check the PHP your web server really runs<\/h2>\n<p>Here is the trap: <code>php -v<\/code> on the command line tells you nothing about the PHP behind your website. FPM pools and mod_php can use another build, and on cPanel every domain can have its own version. So ask the web server itself. The script writes a tiny PHP file with a random name, calls it once and removes it again, even if curl fails:<\/p>\n<pre><code class=\"language-bash\">#!\/usr\/bin\/env bash\n# Ask the web server which PHP it really runs: the CLI can be a different version than FPM\/mod_php.\n# Usage: .\/check-web-php.sh &lt;document root&gt; &lt;base URL&gt;\nset -eu\ndocroot=\"$1\"; base=\"$2\"\nname=\"php-check-$(openssl rand -hex 8).php\"\ntrap 'rm -f \"$docroot\/$name\"' EXIT   # never leave the file behind\nprintf '&lt;?php echo PHP_VERSION, \" \", PHP_SAPI, \" session.upload_progress=\", ini_get(\"session.upload_progress.enabled\") ?: \"0\", PHP_EOL;' &gt; \"$docroot\/$name\"\ncurl -fsS \"$base\/$name\"<\/code><\/pre>\n<pre><code class=\"language-text\">.\/check-web-php.sh \/var\/www\/html\/public https:\/\/myport.ddev.site\n8.4.17 fpm-fcgi session.upload_progress=1<\/code><\/pre>\n<p>Version, SAPI and one setting we will need in a moment, in one line.<\/p>\n<h2>Step 3: Update and restart every worker<\/h2>\n<p>The update is the only real fix. After it, restart all PHP processes, because old workers keep running the old code:<\/p>\n<pre><code class=\"language-bash\"># Debian\/Ubuntu with packages from the distribution or deb.sury.org\nsudo apt update &amp;&amp; sudo apt install --only-upgrade 'php8.4*'\nsudo systemctl restart php8.4-fpm      # PHP-FPM\nsudo systemctl restart apache2         # mod_php: a full restart, not only a reload\n\n# Check again\n.\/check-php2shell.sh<\/code><\/pre>\n<p>On managed or shared hosting you cannot do this yourself. Open a ticket and ask for the exact version, then verify it with the script from step 2. Do not trust &#8220;we are on 8.4&#8221; as an answer.<\/p>\n<h2>Step 4: Reduce the risk if you cannot update today<\/h2>\n<p>The PHP advisory lists a few settings that close specific attack paths. They do not make a server safe, they only buy time. Put them where PHP reads them before parsing the request, so in the FPM pool or <code>php.ini<\/code>, not in <code>.user.ini<\/code> and not with <code>ini_set()<\/code>:<\/p>\n<pre><code class=\"language-ini\">; FPM pool, e.g. \/etc\/php\/8.4\/fpm\/pool.d\/www.conf\nphp_admin_value[memory_limit] = -1\nphp_admin_value[post_max_size] = 8M          ; 32M if you need uploads\nphp_admin_value[upload_max_filesize] = 6M    ; keep it below post_max_size\nphp_admin_flag[session.upload_progress.enabled] = off<\/code><\/pre>\n<p>Yes, <code>memory_limit = -1<\/code> feels wrong. It removes the trigger of one bug, but a single heavy request can now eat the whole server memory, so keep an eye on it and go back to a normal limit after the update. Check the result with a second small script:<\/p>\n<pre><code class=\"language-bash\">#!\/usr\/bin\/env bash\n# Show the settings the PHP advisory names as temporary mitigations\nphp=\"${1:-php}\"\n\"$php\" -r '\nforeach ([\"memory_limit\", \"post_max_size\", \"upload_max_filesize\", \"session.upload_progress.enabled\"] as $key) {\n    printf(\"%-34s %sn\", $key, var_export(ini_get($key), true));\n}'<\/code><\/pre>\n<p>One more thing that I would do even on patched servers: switch off <code>session.upload_progress.enabled<\/code>. Two days after the release the PHP team published a note about CVE-2026-115560, another bug in session upload progress that also affects 8.5.12 and will only be fixed in the next regular release. Most applications never use this feature. TYPO3 and WordPress core do not even use PHP sessions.<\/p>\n<h2>Step 5: Look into your logs<\/h2>\n<p>The attack happens below the application, so TYPO3 or WordPress logs stay quiet. The researchers mention memory-limit fatals, many HTTP 500 answers to POST requests and unusual worker restarts. A quick first look:<\/p>\n<pre><code class=\"language-bash\">#!\/usr\/bin\/env bash\n# Look for the traces the researchers describe: memory-limit fatals and bursts of POST 500s.\n# Usage: .\/hunt-oom.sh &lt;php error log&gt; &lt;access log&gt;\nerrors=\"$1\"; access=\"$2\"\necho \"== memory-limit fatals per day\"\ngrep -h \"Allowed memory size of\" \"$errors\" | sed -E 's\/^[([^ ]+) .*\/1\/' | sort | uniq -c\necho \"== IPs with 5+ POST requests answered with 500\"\nawk '$6 == \"\"POST\" &amp;&amp; $9 == 500 { print $1 }' \"$access\" | sort | uniq -c | sort -rn | awk '$1 &gt;= 5'<\/code><\/pre>\n<pre><code class=\"language-text\">.\/hunt-oom.sh \/var\/log\/php8.4-fpm.log \/var\/log\/apache2\/access.log\n== memory-limit fatals per day\n      2 27-Oct-2026\n== IPs with 5+ POST requests answered with 500\n      6 203.0.113.7<\/code><\/pre>\n<p>A hit is not a proof of an attack, big imports also run out of memory. But a cluster of fatals with many 500s from one IP since 21 October is worth a closer look. If you find something on an unpatched server, treat it as compromised: rotate the passwords and keys from the configuration files, and rebuild instead of cleaning up.<\/p>\n<h2>My takeaway<\/h2>\n<p>Since years I keep TYPO3 and its extensions up to date, but the runtime under it was more like &#8220;the hosting does that&#8221;. PHP2Shell showed me that this layer needs the same attention. The scripts above take five minutes, so please run them on every server you are responsible for, today and not after the weekend.<\/p>\n<p>If this post helped you, I will be really happy. And if your hosting answered with an interesting version number, drop a comment.<\/p>\n<h2>Further reading<\/h2>\n<ul>\n<li><a href=\"https:\/\/www.php.net\/archive\/2026.php\">PHP news archive: security advisory of 21 October 2026 and the session upload progress note<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/php\/php-src\/security\/advisories\/GHSA-w8hw-w9fx-j79w\">GHSA-w8hw-w9fx-j79w: CVE-2026-109618<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/php\/php-src\/security\/advisories\/GHSA-6wmf-4rv5-p3rp\">GHSA-6wmf-4rv5-p3rp: CVE-2026-109619<\/a><\/li>\n<li><a href=\"https:\/\/www.php.net\/manual\/en\/install.fpm.configuration.php\">PHP manual: FPM configuration and php_admin_value<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Two critical bugs in the PHP interpreter allow code execution without login. What PHP2Shell is, and five shell scripts to check versions, settings and logs.<\/p>\n","protected":false},"author":1,"featured_media":192,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[19],"tags":[45,32,43,5,42],"class_list":["post-191","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-php","tag-devops","tag-php-8","tag-security","tag-typo3","tag-wordpress"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>PHP2Shell: check your PHP servers today<\/title>\n<meta name=\"description\" content=\"PHP2Shell (CVE-2026-109618\/109619) explained: why a memory error becomes a shell, fixed versions, and shell scripts to check your servers.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PHP2Shell: check your PHP servers today\" \/>\n<meta property=\"og:description\" content=\"PHP2Shell (CVE-2026-109618\/109619) explained: why a memory error becomes a shell, fixed versions, and shell scripts to check your servers.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/\" \/>\n<meta property=\"og:site_name\" content=\"Hoja Mustaffa Abdul Latheef \u2013 Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-27T09:46:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/php2shell-check-your-servers-with-a-few-shell-scripts.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Hoja Mustaffa Abdul Latheef\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@hojaonline\" \/>\n<meta name=\"twitter:site\" content=\"@hojaonline\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hoja Mustaffa Abdul Latheef\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/\"},\"author\":{\"name\":\"Hoja Mustaffa Abdul Latheef\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"headline\":\"PHP2Shell: check your servers with a few shell scripts\",\"datePublished\":\"2026-10-27T09:46:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/\"},\"wordCount\":1240,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"image\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/php2shell-check-your-servers-with-a-few-shell-scripts.jpg\",\"keywords\":[\"DevOps\",\"PHP 8\",\"Security\",\"TYPO3\",\"WordPress\"],\"articleSection\":[\"PHP\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/\",\"name\":\"PHP2Shell: check your PHP servers today\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/php2shell-check-your-servers-with-a-few-shell-scripts.jpg\",\"datePublished\":\"2026-10-27T09:46:03+00:00\",\"description\":\"PHP2Shell (CVE-2026-109618\\\/109619) explained: why a memory error becomes a shell, fixed versions, and shell scripts to check your servers.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/#primaryimage\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/php2shell-check-your-servers-with-a-few-shell-scripts.jpg\",\"contentUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/php2shell-check-your-servers-with-a-few-shell-scripts.jpg\",\"width\":1200,\"height\":630,\"caption\":\"PHP2Shell: update PHP now\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/php2shell-check-your-servers-with-a-few-shell-scripts\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/hoja.in\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PHP2Shell: check your servers with a few shell scripts\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/\",\"name\":\"Hoja Mustaffa Abdul Latheef \u2013 Blog\",\"description\":\"Notes from daily work with TYPO3, PHP and AI-assisted engineering\",\"publisher\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/hoja.in\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\",\"name\":\"Hoja Mustaffa Abdul Latheef\",\"logo\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/image\\\/\"},\"description\":\"Senior TYPO3 Developer at jweiland.net, TYPO3 CMS Certified Developer. I write about TYPO3 upgrades, extension development, PHP and AI-assisted engineering with Claude Code.\",\"sameAs\":[\"https:\\\/\\\/hoja.in\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PHP2Shell: check your PHP servers today","description":"PHP2Shell (CVE-2026-109618\/109619) explained: why a memory error becomes a shell, fixed versions, and shell scripts to check your servers.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/","og_locale":"en_US","og_type":"article","og_title":"PHP2Shell: check your PHP servers today","og_description":"PHP2Shell (CVE-2026-109618\/109619) explained: why a memory error becomes a shell, fixed versions, and shell scripts to check your servers.","og_url":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/","og_site_name":"Hoja Mustaffa Abdul Latheef \u2013 Blog","article_published_time":"2026-10-27T09:46:03+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/php2shell-check-your-servers-with-a-few-shell-scripts.jpg","type":"image\/jpeg"}],"author":"Hoja Mustaffa Abdul Latheef","twitter_card":"summary_large_image","twitter_creator":"@hojaonline","twitter_site":"@hojaonline","twitter_misc":{"Written by":"Hoja Mustaffa Abdul Latheef","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/#article","isPartOf":{"@id":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/"},"author":{"name":"Hoja Mustaffa Abdul Latheef","@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"headline":"PHP2Shell: check your servers with a few shell scripts","datePublished":"2026-10-27T09:46:03+00:00","mainEntityOfPage":{"@id":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/"},"wordCount":1240,"commentCount":0,"publisher":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"image":{"@id":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/#primaryimage"},"thumbnailUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/php2shell-check-your-servers-with-a-few-shell-scripts.jpg","keywords":["DevOps","PHP 8","Security","TYPO3","WordPress"],"articleSection":["PHP"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/","url":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/","name":"PHP2Shell: check your PHP servers today","isPartOf":{"@id":"https:\/\/hoja.in\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/#primaryimage"},"image":{"@id":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/#primaryimage"},"thumbnailUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/php2shell-check-your-servers-with-a-few-shell-scripts.jpg","datePublished":"2026-10-27T09:46:03+00:00","description":"PHP2Shell (CVE-2026-109618\/109619) explained: why a memory error becomes a shell, fixed versions, and shell scripts to check your servers.","breadcrumb":{"@id":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/#primaryimage","url":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/php2shell-check-your-servers-with-a-few-shell-scripts.jpg","contentUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/php2shell-check-your-servers-with-a-few-shell-scripts.jpg","width":1200,"height":630,"caption":"PHP2Shell: update PHP now"},{"@type":"BreadcrumbList","@id":"https:\/\/hoja.in\/blog\/php2shell-check-your-servers-with-a-few-shell-scripts\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/hoja.in\/blog\/"},{"@type":"ListItem","position":2,"name":"PHP2Shell: check your servers with a few shell scripts"}]},{"@type":"WebSite","@id":"https:\/\/hoja.in\/blog\/#website","url":"https:\/\/hoja.in\/blog\/","name":"Hoja Mustaffa Abdul Latheef \u2013 Blog","description":"Notes from daily work with TYPO3, PHP and AI-assisted engineering","publisher":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/hoja.in\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b","name":"Hoja Mustaffa Abdul Latheef","logo":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/image\/"},"description":"Senior TYPO3 Developer at jweiland.net, TYPO3 CMS Certified Developer. I write about TYPO3 upgrades, extension development, PHP and AI-assisted engineering with Claude Code.","sameAs":["https:\/\/hoja.in\/"]}]}},"_links":{"self":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/comments?post=191"}],"version-history":[{"count":1,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/191\/revisions"}],"predecessor-version":[{"id":193,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/191\/revisions\/193"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/media\/192"}],"wp:attachment":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/media?parent=191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/categories?post=191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/tags?post=191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}