
Высокоточный сканер для php2shell (CVE-2026-109618 и CVE-2026-109619)
Инструмент командной строки для обнаружения CVE-2026-109618 и CVE-2026-109619 в приложениях на PHP.
Сканер отправляет минимальный управляющий multipart-запрос, за которым следуют до трёх специально сформированных multipart-проб. Пробы используют ключи массивов PHP с вложенностью 62 уровня и увеличиваются с 1 MiB до 20 MiB, что соответствует логике обнаружения, используемой внутренним сканером Assetnote.
Цель считается уязвимой, если проба вызывает ошибку исчерпания памяти PHP, дифференциальный пустой HTTP 500, сбой воркера PHP-FPM или если заявленная версия PHP известна как неисправленная. Исходные ответы 5xx, распространённые статусы отклонения запроса и непустые ответы HTTP 500 без сигнатуры фатальной ошибки PHP не рассматриваются как признаки сбоя.
По умолчанию сканер проверяет /index.php. Путь, указанный в URL, сохраняется, а --path или --path-file позволяют проверять пользовательские пути. Цели phpMyAdmin автоматически повторно проверяются по адресу /show_config_errors.php. Перенаправления не отслеживаются.
Режим по умолчанию --sapi auto применяет правила вердикта как для mod_php, так и для PHP-FPM, соответствуя комбинированному поведению постмодулей Assetnote. Используйте --sapi mod_php или --sapi fpm, чтобы ограничить обнаружение известным SAPI.
Каждый проверяемый путь может получить управляющий запрос размером 42 байта и три пробы общим объёмом около 29 MiB. Зондирование прекращается, как только вердикт установлен, а дублирующиеся входные URL сканируются один раз.
pip install -r requirements.txt
Сканирование одного хоста:
python3 scanner.py -u https://example.com
Сканировать список хостов:
python3 scanner.py -l hosts.txt
Сканирование в несколько потоков и сохранение результатов:
python3 scanner.py -l hosts.txt -t 20 -o results.json
Сканирование с пользовательскими заголовками:
python3 scanner.py -u https://example.com -H "Authorization: Bearer token" -H "Cookie: session=abc"
Сканирование пользовательского пути:
python3 scanner.py -u https://example.com --path /phpinfo.php
python3 scanner.py -u https://example.com --path /index.php --path /admin.php
python3 scanner.py -u https://example.com --path-file paths.txt
Использовать только правила вердикта PHP-FPM:
python3 scanner.py -u https://example.com --sapi fpm
-u, --url Single URL to check
-l, --list File containing hosts (one per line)
-t, --threads Number of concurrent threads (default: 10)
--timeout Request timeout in seconds (default: 60)
-o, --output Output file for results (JSON)
--all-results Save all results, not just vulnerable hosts
-k, --insecure Disable TLS certificate verification
-H, --header Custom header (can be used multiple times)
-v, --verbose Show verdict reasons and response snippets
-q, --quiet Only output vulnerable hosts
--no-color Disable colored output
--sapi Verdict rules: auto, mod_php, or fpm (default: auto)
--path Custom path to test (can be used multiple times)
--path-file File containing paths to test (one per line)
Первооткрывателем php2shell является команда Calif. Их отчёт можно прочитать здесь: https://calif.io/php2shell/.
Сканер был создан командой Assetnote Security Research Team на основе логики, разработанной для Searchlight's Exposure Platform.
Результаты выводятся в терминал. При использовании -o уязвимые хосты сохраняются в JSON-файл с указанием причины вердикта и отредактированными доказательствами в виде HTTP-запроса и ответа.
При определённых конфигурациях PHP сканер может сообщать о ложноположительном результате, когда его multipart-проба превышает memory_limit PHP. В этом случае исправленные и уязвимые версии могут возвращать одинаковый пустой ответ HTTP 500.
Это было воспроизведено на исправленном PHP 8.4.27 со значениями memory_limit от 2M до 32M, а также на PHP 8.3.36 при 128M, когда max_multipart_body_parts установлен в 2785 или выше. Точный порог может различаться между сборками.
Когда PHP не раскрывает свою версию, сканер не может отличить эту безопасную OOM-ситуацию после установки патча от уязвимого поведения до установки патча. Поэтому результаты следует проверять с учётом установленной версии PHP и любых исправлений от производителя.