
# Docker-лаборатория CTF, демонстрирующая CVE-2024-4577 — внедрение аргументов PHP-CGI, приводящее к RCE Включает уязвимый PHP 5.4.1 CGI, эксплойт-скрипты и получение флага.
Автономный Docker-лабораторный стенд с нуля, демонстрирующий реальный
примитив argument-injection → Remote Code Execution, лежащий в основе
CVE-2024-4577. Эксплуатируйте его через http://localhost:8080, получите
шелл и прочитайте флаг изнутри контейнера.
Это настоящая уязвимость, а не симуляция. Контейнер компилирует непропатченный бинарник PHP 5.4.1 CGI и подключает его к Apache ровно так, как настраиваются реальные уязвимые хосты. Никакой фейковой проверки "if password == flag" здесь нет — единственный способ получить флаг — это реально добиться выполнения кода.
Сигнатурный payload для CVE-2024-4577 использует %AD (мягкий дефис).
Этот трюк работает только на Windows, потому что "Best-Fit" кодировка
символов Windows преобразует байт 0xAD в настоящий - (0x2D) после
того, как патч PHP для CVE-2012-1823 уже проверил строку запроса. Это
преобразование кодировки выполняется самой Windows — оно не происходит
внутри обычного Linux Docker-контейнера.
Поэтому честный, работающий на вашей машине Linux-стенд воспроизводит
ровно тот же примитив RCE — инъекцию опций php-cgi через URL → -d auto_prepend_file=php://input → выполнение кода — используя буквальную
форму - (которая является родительским багом CVE-2024-4577 —
CVE-2012-1823). Единственное отличие от реальной Windows-цели
CVE-2024-4577 — это слой обхода кодировки %AD→-, который полностью
описан в этом README (см. Как это работает
и poc.http).
| Этот Linux-стенд | Реальный CVE-2024-4577 (Windows) | |
|---|---|---|
| Уязвимый компонент | php-cgi | php-cgi |
| Примитив RCE | -d auto_prepend_file=php://input | идентичен |
| Разделитель в URL | буквальный - | %AD (best-fit → -) |
| Обходит патч 2012 года? | Н/П (PHP старше патча) | Да, через Windows best-fit |
| Работает на Win 11 Home + Docker Desktop | ✅ | ❌ (нужны Windows-контейнеры) |
Если вам нужна именно побитовая Windows-репродукция с %AD, вам понадобится
Docker-хост с поддержкой Windows-контейнеров (Windows Server / Win Pro +
Hyper-V) — на Windows 11 Home это не запустится. Windows-payload включён в
poc.http для справки.
CVE-2024-4577 — PHP CGI Argument Injection, приводящая к Remote Code Execution. Обнаружена DEVCORE (Orange Tsai / Angelboy), раскрыта 2024-06-06.
Когда PHP развёрнут в CGI-режиме (или бинарник php-cgi.exe иным образом
доступен) на Windows с определёнными системными локалями (традиционный/
упрощённый китайский, японский и другие), веб-сервер передаёт строку запроса
HTTP в php-cgi как аргументы командной строки. Атакующий может протащить
опции командной строки php-cgi (-d ...) в эту строку запроса. Best-fit
преобразование кодовой страницы Windows превращает байт мягкого дефиса 0xAD
(%AD) в ASCII-дефис -, который проскальзывает мимо защиты CVE-2012-1823 и
позволяет атакующему задавать произвольные INI-директивы PHP — наиболее
полезная из них auto_prepend_file=php://input с allow_url_include=1,
которая выполняет тело запроса атакующего как PHP. Результат:
неаутентифицированное удалённое выполнение кода. Уязвимость была
вооружена в дикой природе в течение нескольких дней (например, ransomware
TellYouThePass).
CGI передаёт строку запроса как argv. Согласно RFC 3875, если строка
запроса CGI-запроса не содержит незакодированного =, сервер
разбивает её по +, URL-декодирует каждое слово и передаёт слова CGI-
программе как аргументы командной строки. Таким образом, php-cgi
получает контролируемый атакующим argv.
php-cgi разбирает этот argv как опции. Исторически php-cgi
интерпретировал -d key=value, -T и т.д. из этого argv. Передача
-d allow_url_include=1 -d auto_prepend_file=php://input заставляет PHP
выполнять тело запроса как код → CVE-2012-1823.
Исправление CVE-2012-1823 неполно на Windows. Патч 2012 года добавил
защиту в sapi/cgi/cgi_main.c: примерно "если (сырая) строка запроса
начинается с - и не содержит =, пропустить разбор опций
(skip_getopt)." Атакующий, отправляющий буквальный -, теперь
заблокирован.
Best-fit кодировка обходит защиту (баг 2024 года). На Windows PHP
преобразует командную строку, используя кодовую страницу локали с
включённым best-fit сопоставлением. Атакующий отправляет %AD
(байт 0xAD, мягкий дефис). В момент проверки защиты первый байт — 0xAD,
не -, поэтому skip_getopt не устанавливается. Позже, когда PHP
фактически строит argv, Windows best-fit-сопоставляет 0xAD → -, и
теперь getopt видит -d. Инъекция опций срабатывает после проверки,
которая должна была её остановить. Этот порядок "сначала проверка, потом
преобразование" и есть вся уязвимость.
В этом Linux-стенде шаги 1–2 воспроизводятся точно с php-cgi, который предшествует патчу шага 3, поэтому буквальная форма
-работает и демонстрирует идентичный RCE. Шаг 4 — это слой только для Windows, задокументированный, но не выполняемый (в Linux нет best-fit преобразования).
Исправлено в 8.3.8, 8.2.20, 8.1.29. Следовательно, уязвимы:
Условия: ОС Windows; PHP работает как CGI или php-cgi.exe доступен
(конфигурация по умолчанию XAMPP на Windows уязвима); затронутая локаль
для best-fit пути. (Родительский баг CVE-2012-1823 — примитив, который
запускает этот стенд — затрагивает любую ОС, работающую с php-cgi до
исправления 2012 года в этой конфигурации.)
cve-2024-4577-lab/ ├── Dockerfile # builds the lab: compiles unpatched PHP 5.4.1 CGI + Apache ├── Dockerfile.vulhub # fallback: prebuilt vulnerable base image (if compile fails) ├── docker-compose.yml # one-command build+run, maps localhost:8080 -> 80 ├── start.sh # container entrypoint (Apache foreground) ├── exploit.sh # one-shot RCE PoC (bash + curl) ├── poc.http # raw HTTP requests (Linux payload + real Windows %AD payload) ├── app/ │ └── index.php # ordinary web page (NOT itself vulnerable) ├── config/ │ ├── apache-vhost.conf # the vulnerable Apache <-> php-cgi wiring │ └── php.ini # minimal php.ini (cgi.force_redirect=0, etc.) ├── flag.txt # the flag (copied to /flag.txt in the container) └── README.md # this file
## 5. Предварительные требования
- **Docker Desktop** (Windows/macOS) или Docker Engine (Linux).
Windows 11 Home: установите Docker Desktop с бэкендом **WSL 2** (по умолчанию).
→ https://www.docker.com/products/docker-desktop/
- `curl` для эксплуатации (`curl.exe` встроен в Windows 10/11; также доступен в
Git Bash / WSL / macOS / Linux).
- Доступ в интернет **во время сборки** (загружается исходный код PHP 5.4.1).
## 6. Инструкции по сборке
Откройте терминал в папке `cve-2024-4577-lab/`.
### Вариант A — docker compose (рекомендуется)```bash
docker compose up --build -d