Перейти к содержимому
← Каталог php Deserialization

Deserialization: unserialize() без allowed_classes

Cookie user_prefs десериализуется через unserialize() — подделайте объект с магическим __wakeup() и получите админские права.

mediumphpPro
Задача
# Лаба: Insecure Deserialization — unserialize() без allowed_classes ## Сценарий SecureShop — интернет-магазин на нативном PHP. После успешного логина приложение сохраняет пользовательские настройки интерфейса (тема оформления, язык) в cookie `user_prefs`. В этой cookie хранится сериализованный PHP-объект класса `UserPreferences`, закодированный в base64. На странице `/profile` сервер декодирует cookie из base64 и восстанавливает объект через `unserialize()`, чтобы отобразить тему и язык, выбранные пользователем. Беглый просмотр исходников магазина показывает, что в кодовой базе живёт ещё один класс — `DevOverride`. Его использовали на этапе разработки для CLI-утилит, и он содержит магический метод `__wakeup()`, который помечает текущий запрос как админский через глобальный флаг. В production-сборке этот класс нигде не инстанцируется, но autoload PHP загружает его вместе со всеми остальными — а значит, он остаётся доступен для `unserialize()`. ## Почему это опасно `unserialize()` в PHP — не «разобрать строку в массив». Это полноценное восстановление объектов: PHP создаёт экземпляр указанного в строке класса и сразу вызывает на нём магические методы (`__wakeup`, `__destruct`, `__toString`, `__call`). Контролируя имя класса в строке, атакующий выбирает, какой класс из autoload будет создан, и провоцирует исполнение его магических методов с побочными эффектами. В реальных POP-цепочках Laravel/Symfony/Monolog такие gadget'ы соединяются в цепочки и достигают RCE. Вы залогинились как обычный пользователь `demo` (роль `user`). На `/profile` флаг не отображается — он показывается только пользователям с ролью `admin` или когда выставлен внутренний dev-флаг. Ваша задача — подменить cookie `user_prefs` так, чтобы `unserialize()` создал экземпляр класса-гаджета, его магический метод сработал автоматически, и сервер выдал вам CTF-флаг. ## Цели 1. Проанализировать обработчик профиля в `internal/handlers/handlers.php` — определить, какой cookie декодируется и какие классы доступны в приложении через autoload. 2. Собрать вручную строку сериализации PHP-объекта с произвольным значением свойства, опираясь на формат `O:<len>:"ClassName":<n>:{<props>}`. 3. Закодировать полезную нагрузку в base64, URL-encode и подставить в cookie `user_prefs`, чтобы при заходе на `/profile` сервер вернул CTF-флаг. ## Данные | Параметр | Значение | |----------|----------| | Обычный пользователь | `demo` / `demo` | | Уязвимый endpoint | `GET /profile` | | Cookie для атаки | `user_prefs` (base64 + serialize) | | Класс-gadget в коде | `DevOverride` (смотри `internal/handlers/handlers.php`) |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru