
Эксплойт для CVE-2026-17544: внеграничная запись (OOB write) в PHP bcmath, преобразованная в RCE, действующий только в памяти, с обходом disable_functions и open_basedir с помощью рантайм-резолвера без смещений.
Боевой proof-of-concept для CVE-2026-17544 — выхода за границы буфера при записи в переписанном расширении bcmath в PHP (bc_str2num). Он превращает публично известный крах с только DoS в полный, универсальный, работающий только с памятью примитив удалённого выполнения кода, который обходит одновременно disable_functions и open_basedir.
Только авторизованные исследования / образовательное использование. Запускайте это только против систем, которыми вы владеете или на тестирование которых у вас есть явное разрешение.
![]()
bc_str2num отбрасывает дробную часть при ручном scale, повторно обрезает завершающие нули, но не обновляет fractional_end. Буфер выделяется под обрезанную длину, а копирование использует длину до обрезки → контролируемая OOB-запись нулей в кучу Zend MM.zend_string (длина сохраняется) → UAF из-за рассинхронизации счётчика ссылок → относительное чтение/запись через гигантскую строку → fault-safe абсолютное произвольное чтение → разрешение символов во время выполнения → полностью data-only вызов нативной функции.zend_class_entry + встроенный function_table + фейковый zend_function{ handler = zif_shell_exec }, затем вызывает его как метод. Вывод команды возвращается в виде строки и попадает в ответ/stdout..data и целевой символ определяются во время выполнения сканированием памяти — поэтому один и тот же файл работает в разных сборках и дистрибутивах.Это примитив побега из песочницы / пост-эксплуатации, а не RCE только на основе удалённого ввода.
| Сценарий | Результат |
|---|---|
Атакующий уже может выполнять PHP (веб-шелл, десериализация, eval-приёмник), но ограничен disable_functions + open_basedir | ✅ Нативный RCE (этот PoC) |
| Приложение просто вызывает функцию bcmath для необработанного пользовательского ввода, например |
Один вызов bcmath на основе ввода атакующего даёт одну слепую OOB-запись нулей без обратной связи. Полный RCE требует произвольного выполнения PHP, чтобы подготовить кучу, построить примитивы чтения/записи и запустить резолвер — ничто из этого не выражается аргументом функции. Поэтому реалистичный максимум при воздействии только через ввод — это удалённый отказ в обслуживании; выполнение кода требует уже существующего контекста выполнения PHP, который этот PoC затем освобождает из песочницы.
Баг живёт только в переписанном bcmath (линейки PHP 8.4 / 8.5):
Проверено end-to-end (uid=0, вывод перехвачен) на PHP 8.4.23 и PHP 8.5.8, amd64, одним и тем же неизменённым файлом — компоновка структур Zend идентична в 8.4 / 8.5.
bcmath..text до ELF-заголовка; это безопасно для любого бинарника с непрерывным отображением. Только искусственные сборки с -z separate-code, имеющие непокрытые промежутки в 2 МБ, не могут быть разрешены автоматически слепым сканированием (в продакшене не встречаются).exit() в рамках одного запроса не убивал сервер: php-fpm, Apache mod_php или встроенный сервер с PHP_CLI_SERVER_WORKERS>0.php exploit.php "id; uname -a"
Разместите, например, как shell.php, затем:
GET /shell.php?cmd=id
POST cmd=id
Вывод команды перехватывается через zif_shell_exec и записывается в тело ответа.
bccomp(), чтобы OOB-запись нулей попала только в счётчик ссылок соседней zend_string (длина сохраняется).zend_reference (через косвенную адресацию) даёт fault-safe абсолютное произвольное чтение, которое никогда не затрагивает заголовок со счётчиком ссылок цели..text: спускайтесь постранично до ELF-магии (база), разберите программные заголовки, чтобы найти .data, затем просканируйте .data в поисках zend_function_entry для shell_exec, чей обработчик указывает в .text.zend_class_entry, инлайновый с одной корзиной (bucket) (корректный хеш , завершённая цепочка коллизий) и фейковый , чей обработчик — ; испортьте указатель на класс у объекта-зонда и вызовите метод. Вывод возвращается и выводится.exploit.php — универсальный эксплойт, работающий только с памятью (CLI + web).Предоставлено для исследований в области безопасности и образования. Автор не несёт ответственности за неправомерное использование. Не разворачивайте против систем, которые вам не разрешено тестировать.
bccomp($_POST['v'])| ❌ Только DoS / крах |
| Ветка PHP | Уязвима |
|---|
| 7.x, 8.0 – 8.3 | Нет (старый libbcmath, другой bc_str2num) |
| 8.4.0 – 8.4.23 | Да |
| 8.5.0 – 8.5.8 | Да |
| ≥ 8.4.24 / ≥ 8.5.9 | Исправлена |
function_tablezend_stringzend_internal_functionzif_shell_exec