Disable Functions Bypass - dl Function

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks

dl() дозволяє PHP завантажувати спільне розширення під час виконання. Якщо ви можете змусити його завантажити модуль під контролем атакуючого, ви можете зареєструвати нову PHP-функцію, яка всередині викликає execve, system, або будь-яку іншу нативну примітиву і таким чином обійти disable_functions.

Це реальний примітив, але на сучасних цілях він набагато рідше зустрічається, ніж стверджують старі writeups.

Чому цей bypass рідко зустрічається сьогодні

Основні перешкоди:

  • dl() повинен існувати і не повинен бути відключений
  • enable_dl повинен все ще дозволяти динамічне завантаження
  • Цільовий SAPI повинен підтримувати dl()
  • The payload must be a valid PHP extension compiled for the same target ABI
  • Розширення має бути доступне з налаштованої extension_dir

Офіційний PHP-мануал — найважливіша перевірка реальності: dl() доступна лише для CLI та embed SAPIs, а для CGI SAPI — коли її запускають з командного рядка. Це означає, що техніка зазвичай недоступна в звичайних веб-запитах PHP-FPM/mod_php, тож перевірте SAPI перед тим, як витрачати час на створення payload.

Також зауважте, що enable_dl — це налаштування INI_SYSTEM і, починаючи з PHP 8.3.0, PHP документує його як deprecated, тому зазвичай ви не можете змінити його під час виконання з PHP-коду під контролем атакуючого.

Якщо dl() непридатна, поверніться до більш широкого списку module/version dependent bypasses.

Швидка попередня оцінка з foothold

Перш ніж щось будувати, зберіть точні параметри, яким має відповідати модуль:

<?php
phpinfo();
echo "PHP_VERSION=" . PHP_VERSION . PHP_EOL;
echo "PHP_SAPI=" . php_sapi_name() . PHP_EOL;
echo "ZTS=" . (PHP_ZTS ? "yes" : "no") . PHP_EOL;
echo "INT_BITS=" . (PHP_INT_SIZE * 8) . PHP_EOL;
echo "enable_dl=" . ini_get("enable_dl") . PHP_EOL;
echo "extension_dir=" . ini_get("extension_dir") . PHP_EOL;
echo "disabled=" . ini_get("disable_functions") . PHP_EOL;
?>

Що має значення:

  • PHP_SAPI: якщо це fpm-fcgi або apache2handler, dl() зазвичай марна для веб-експлуатації
  • extension_dir: payload має бути завантажений звідси
  • PHP Version, архітектура, debug/non-debug і ZTS/non-ZTS: ваш модуль має співпадати з ними
  • disable_functions: підтвердіть, чи dl відсутній через те, що він відключений, чи через те, що SAPI його не підтримує

Practical exploitation constraints

1. You normally need write access to extension_dir

Це найбільший вузький місце.

dl() приймає ім’я файлу розширення, а PHP завантажує його з extension_dir. На практиці це означає, що звичайне довільне завантаження файлу до /var/www/html/uploads недостатнє. Потрібен шлях, щоб помістити .so/.dll туди, звідки PHP реально завантажує розширення.

Реалістичні ситуації, де це стає експлуатованим:

  • CTFs або навмисно вразливі лабораторії, де extension_dir доступний для запису
  • помилки спільного хостингу або контейнерів, які відкривають записуваний шлях розширень
  • окремий примітив довільного запису файлу, який вже дістає до extension_dir
  • сценарії post-exploitation, де ви вже підняли привілеї достатньо, щоб залишити там файли

2. The module must match the target build

Співпадіння тільки з PHP_VERSION недостатнє. Розширення також має відповідати:

  • ОС та архітектурі CPU
  • очікуванням libc/toolchain
  • ZEND_MODULE_API_NO
  • debug vs non-debug збірці
  • ZTS vs NTS

Якщо вони не співпадають, dl() зазнає невдачі або спричинить крах процесу.

3. open_basedir is not the main defense here

Якщо ви можете помістити модуль у extension_dir і викликати dl(), код розширення виконується всередині процесу PHP. У цей момент релевантним бар’єром була не open_basedir, а здатність розмістити валідний shared object у шляху завантаження розширень.

Building the malicious extension

Класичний шлях все ще дійсний:

  1. Відтворіть збірку жертви якомога ближче
  2. Використайте phpize, ./configure та make, щоб зібрати shared extension
  3. Експортуйте PHP-функцію, наприклад bypass_exec($cmd), яка обгортає нативне виконання команд
  4. Завантажте скомпільований модуль у extension_dir
  5. Завантажте його за допомогою dl() і викличте експортовану функцію

Атака стара, але досі релевантна, оскільки changelogs PHP 8.x продовжують містити виправлення крахів, специфічних для dl(). Примітив усе ще існує; складність у знаходженні середовища, де він досяжний і куди можна помістити відповідний модуль.

Minimal workflow

On the attacker box

mkdir bypass && cd bypass
phpize
./configure
make

Отриманий shared object зазвичай розміщується в modules/.

Якщо ви збираєте в іншому середовищі, ніж target, вважайте згенерований файл чернеткою, поки не перевірите, що ABI відповідає victim.

Завантаження та використання розширення

Якщо target дійсно підтримує dl() і модуль знаходиться в extension_dir, то на стороні виконання все просто:

<?php
if (!extension_loaded('bypass')) {
dl('bypass.so'); // use the correct filename for the target platform
}
echo bypass_exec($_GET['cmd']);
?>

На Windows ім’я файлу зазвичай має розширення .dll, а на Unix-подібних цілях зазвичай — .so.

Примітки нападника

  • Не припускайте, що це працює віддалено лише тому, що function_exists("dl") повертає true в якійсь документації чи старому описі; перевірте живий SAPI
  • Невдала спроба dl() може призвести до падіння PHP worker, якщо модуль несумісний
  • Починаючи з PHP 8, відключені функції видаляються з таблиці функцій, тому їх перелік у userland може відрізнятися від старіших публікацій
  • Якщо ви не можете записувати в extension_dir, ця техніка зазвичай менш практична, ніж FPM/FastCGI, LD_PRELOAD або обхідні шляхи, специфічні для модулів, які вже розглянуто в цьому розділі

Посилання

Tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримайте HackTricks