PHP - Deserialization + Autoload Classes
First, you should check what are Автозавантаження класів.
PHP десеріалізація + spl_autoload_register + LFI/Gadget
Ми знаходимося в ситуації, коли знайшли десеріалізацію PHP у веб-додатку без жодної бібліотеки, вразливої до гаджетів всередині phpggc
. Однак у тому ж контейнері була інша веб-додаток composer з вразливими бібліотеками. Тому метою було завантажити завантажувач composer іншого веб-додатку і зловживати ним, щоб завантажити гаджет, який експлуатуватиме цю бібліотеку з гаджетом з веб-додатку, вразливого до десеріалізації.
Кроки:
Ви знайшли десеріалізацію, і в поточному коді програми немає жодного гаджета
Ви можете зловживати функцією
spl_autoload_register
на кшталт наступної, щоб завантажити будь-який локальний файл з розширенням.php
Для цього ви використовуєте десеріалізацію, де ім'я класу буде всередині
$name
. Ви не можете використовувати "/" або "." в імені класу в серіалізованому об'єкті, але код замінює підкреслення ("_") на слеші ("/"). Тож ім'я класу, таке якtmp_passwd
, буде перетворено на/tmp/passwd.php
, і код спробує його завантажити. Приклад гаджета буде:O:10:"tmp_passwd":0:{}
Якщо у вас є завантаження файлів і ви можете завантажити файл з розширенням .php
, ви можете безпосередньо зловживати цією функціональністю і отримати вже RCE.
У моєму випадку у мене не було нічого подібного, але всередині того ж контейнера була інша веб-сторінка композера з бібліотекою, вразливою до гаджета phpggc
.
Щоб завантажити цю іншу бібліотеку, спочатку потрібно завантажити завантажувач композера тієї іншої веб-аплікації (оскільки завантажувач поточної аплікації не зможе отримати доступ до бібліотек іншої). Знаючи шлях до аплікації, ви можете досягти цього дуже легко за допомогою:
O:28:"www_frontend_vendor_autoload":0:{}
(У моєму випадку завантажувач композера був у/www/frontend/vendor/autoload.php
)Тепер ви можете завантажити інший завантажувач композера аплікації, тому настав час
згенерувати phpgcc
payload для використання. У моєму випадку я використовувавGuzzle/FW1
, що дозволило мені записувати будь-який файл у файловій системі.ЗАУВАЖТЕ: згенерований гаджет не працював, щоб він працював, я модифікував цей payload
chain.php
phpggc і встановив всі атрибути класів з приватних на публічні. Якщо ні, після десеріалізації рядка атрибути створених об'єктів не мали жодних значень.Тепер у нас є спосіб завантажити інший завантажувач композера аплікації і мати phpggc payload, який працює, але нам потрібно зробити це в ТІЙ ЖЕ ЗАПИТІ, щоб завантажувач був завантажений, коли гаджет використовується. Для цього я надіслав серіалізований масив з обома об'єктами, як:
Ви можете побачити спочатку завантажувач, що завантажується, а потім payload
Тепер ми можемо створити та записати файл, однак користувач не міг записувати в жодну папку всередині веб-сервера. Отже, як ви можете бачити в payload, PHP викликає
system
з деяким base64, який створюється в/tmp/a.php
. Потім ми можемо повторно використовувати перший тип payload, який ми використовували як LFI, щоб завантажити завантажувач composer іншого веб-додатку для завантаження згенерованого/tmp/a.php
файлу. Просто додайте його до гаджета десеріалізації:
Резюме корисного навантаження
Завантажити автозавантаження композера іншого веб-додатку в тому ж контейнері
Завантажити гаджет phpggc для зловживання бібліотекою з іншого веб-додатку (первинний веб-додаток, вразливий до десеріалізації, не мав жодного гаджета у своїх бібліотеках)
Гаджет створить файл з PHP корисним навантаженням у /tmp/a.php з шкідливими командами (користувач веб-додатку не може записувати в жодну папку жодного веб-додатку)
Остання частина нашого корисного навантаження буде використовувати завантажити згенерований php файл, який виконає команди
Мені потрібно було викликати цю десеріалізацію двічі. У моєму тестуванні, перший раз файл /tmp/a.php
був створений, але не завантажений, а вдруге його було правильно завантажено.
Last updated