Exploits the interaction between php_serialize and php session handlers: when one endpoint writes sessions with php_serialize (Laravel, Symfony default) and another reads with the php handler (PHP default), injected pipe characters cause arbitrary deserialization at session_start(). 12 built-in POP chains covering current and legacy library versions: - monolog3-fw: Monolog 3.0+ (tested 3.12.1, latest) - laravel10-cmd/fw: illuminate 10.0-13.x+ (tested v13.38.0, latest) - monolog-cmd/fw: Monolog 1.17.2-2.x - laravel-cmd/fw: illuminate 5.4-8.x - guzzle-fw: Guzzle 4.0-7.x - symfony-cmd/fw: Symfony 2.6-4.4.18 - wordpress-cmd/fw: WordPress 6.4.0-6.4.1 All chains tested end-to-end through the full HTTP exploit flow on PHP 8.3. Accepts custom phpggc chains via --chain-file.
26 lines
688 B
PHP
26 lines
688 B
PHP
<?php
|
|
/**
|
|
* Test endpoint: php_serialize handler.
|
|
* Stores POST parameters in $_SESSION.
|
|
*
|
|
* In the wild, this maps to any endpoint that:
|
|
* - Uses ini_set('session.serialize_handler', 'php_serialize')
|
|
* (Laravel, Symfony, etc.)
|
|
* - Stores user input in $_SESSION
|
|
*/
|
|
ini_set('session.serialize_handler', 'php_serialize');
|
|
session_start();
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
foreach ($_POST as $k => $v) {
|
|
$_SESSION[$k] = $v;
|
|
}
|
|
echo json_encode(['status' => 'ok', 'session_id' => session_id()]);
|
|
} else {
|
|
echo json_encode([
|
|
'status' => 'ready',
|
|
'session_id' => session_id(),
|
|
'handler' => 'php_serialize',
|
|
]);
|
|
}
|