Перейти к содержимому

Поиск по платформе

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

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

Автор: Hack & Fix
Освоишь: strict equality (===)typed schema
Средне+60 XP ~35 мин php
CWE-704 · A03:2021 Pro
Обложка: Type Juggling: JSON-аутентификация с loose comparison Обложка: Type Juggling: JSON-аутентификация с loose comparison
Задача
# Манипуляция типами: JSON-логин и число вместо строки ## Сценарий Магазин часов **TimeMall** несколько лет жил с мобильным приложением на старом стеке, и для него остался отдельный JSON-эндпоинт входа: клиент присылает имя пользователя и пароль, который исторически приходит уже хэшированным — отдельная колонка осталась от старой системы. Обычная веб-форма входа при этом использует другой, аккуратный механизм. Перед редизайном приложения команда решила проверить, нельзя ли войти администратором через мобильный API, не зная пароля, — вас пригласили провести проверку. ## Цель 1. Изучите JSON-эндпоинт мобильного входа: какие типы значений он принимает и как сравнивает присланный секрет с хранимым. 2. Войдите под учётной записью администратора, не зная её пароля, — за счёт типа значения в JSON, а не подбора секрета. 3. С полученной сессией обратитесь к эндпоинту текущего пользователя и заберите флаг. ## Теория **Манипуляция типами (type juggling)** в JSON-контексте опаснее, чем в формах. Данные формы всегда приходят строками, а JSON-парсер сохраняет типы: число остаётся числом, булев тип — булевым. Если такой разнотипный ввод попадает в нестрогое сравнение со строкой, PHP приводит строку к числу — и строка хэша особого числового формата превращается в конкретное число. Тогда число, присланное атакующим, «равно» любому хэшу этого формата: содержимое секрета перестаёт иметь значение. **Уязвимый паттерн:** ```php $data = json_decode($raw, true); if ($password == $row['password_md5']) { // число == строка-хэш ``` Механика словами: сравнение покидает мир байтов, как только слева оказывается не строка. Число справа от оператора «сравнивается» не с текстом хэша, а с числом, в которое этот текст превратился при приведении. Для хранимых секретов определённого формата это даёт равенство с элементарным значением — и аутентификация проходит без знания секрета. Парная ошибка — отсутствие проверки типа поля до сравнения: пока эндпоинт принимает что угодно, один лишь оператор сравнения не спасает. ## Точка входа атаки `POST /api/login` — JSON-тело с полями `username` и `password` (Content-Type: application/json). После входа: `GET /api/me` — по сессионной cookie или заголовку авторизации; в ответе для административной роли появляется флаг. * **Обычный пользователь:** `demo` / `demo` * **Целевая учётная запись:** `admin`

Похожие лабораторные (2)

другие лабы по этой уязвимости
Обложка лабы: Type Juggling: ошибочная интерпретация strcmp() Обложка лабы: Type Juggling: ошибочная интерпретация strcmp()
Type Jug

Type Juggling: ошибочная интерпретация strcmp()

На PHP 8.2 эндпоинт /promo приводит ввод к строке, но принимает `strcmp(...) < 1`: любой отрицательный результат ошибочно считается совпадением секретного токена.

+60 XP
PHP Pro
Exploit Fix
Обложка лабы: Type Juggling: Magic Hash Collision Обложка лабы: Type Juggling: Magic Hash Collision
Type Jug

Type Juggling: Magic Hash Collision

API-логин через токен использует loose comparison (==) между md5-хэшами. Magic hash вида 0e[0-9]+ интерпретируется как научная нотация (0.0), что приводит к коллизии хэшей и обходу аутентификации.

+30 XP
PHP Pro
Exploit Fix