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

Type Juggling: JSON-аутентификация с loose comparison

JSON-API логина сравнивает пароль с хешем через loose == . В БД хранится хеш-строка вида 0e830... (magic hash), которая коэрсится в число 0.0. Отправив {"password": 0}, атакующий заходит как admin.

mediumphpPro
Задача
# SecureShop — Legacy mobile API login Магазин SecureShop много лет выпускал мобильное приложение на старом стеке, и у него остался отдельный endpoint для логина — `POST /api/login`. Он принимает JSON-тело вида: ```json {"username": "admin", "password": "<md5 пароля>"} ``` Исторически пароли для мобильного API хранились отдельной колонкой `password_md5` — legacy-миграция из старого магазина, когда пароль приходил с клиента уже как MD5-строка. ## Что доступно - `POST /api/login` — JSON-логин (Content-Type: application/json). При успехе возвращает `{"token": "...", "role": "..."}` и ставит cookie `session_token`. - `GET /api/me` — возвращает текущего пользователя (по cookie или заголовку `Authorization: Bearer <token>`). Если роль `admin` — в ответе лежит поле `flag`. - Также есть обычный HTML-UI (`/login`, `/catalog`, `/profile`, `/admin`) — он тебе для эксплойта не нужен, но посмотреть можно. ## Пользователи | Пользователь | Пароль | Роль | |--------------|--------|------| | `admin` | неизвестен (длинный, случайный) | admin | | `demo` | `demo` | user | ## Данные | Параметр | Значение | |----------|----------| | Уязвимый эндпоинт | `POST /api/login` (Content-Type: application/json) | | Эндпоинт текущего пользователя | `GET /api/me` (cookie или `Authorization: Bearer ...`) | | HTML-UI | `/login`, `/catalog`, `/profile`, `/admin` (для атаки не нужны) | ## Цель Зайти как `admin` через `POST /api/login` **не зная его пароля**. После успешного логина вызвать `GET /api/me` и получить `flag` из ответа. ## Вектор Загляни в обработчик JSON-логина. Подумай, что происходит, когда `json_decode` встречает **числовое** значение в поле `password`, и как это значение потом сравнивается с хешем из БД. Уязвимость известна как **PHP type juggling / "magic hash"** — класс ошибок, где loose-сравнение `==` между строкой и числом коэрсит строку в число по неочевидным правилам.
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru