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

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

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

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

Автор: Hack & Fix
Освоишь: strict equality (===)typed schema
Средне+60 XP ~35 мин php
CWE-704 · A03:2021 Pro
Обложка: Type Juggling: ошибочная интерпретация strcmp() Обложка: Type Juggling: ошибочная интерпретация strcmp()
Задача
# Манипуляция типами: знаковый результат сравнения строк ## Сценарий Книжный магазин **BookFox** запустил акцию: на закрытой промо-странице постоянный покупатель вводит секретный токен и получает дорогой служебный товар в заказ бесплатно. Токен — длинная случайная строка, подобрать её невозможно, и в базе она лежит одна. Но разработчик, писавший проверку, неверно истолковал результат функции сравнения строк — и страница промо принимает за «правильный» совсем не тот ввод, который задумывался. Перед публичным анонсом акции менеджер попросил вас убедиться, что бесплатный товар достаётся только обладателям токена. ## Цель 1. Войдите как обычный покупатель и изучите промо-страницу: что происходит после отправки токена. 2. Обойдите проверку токена, не зная секретного значения. 3. Получите бесплатный заказ служебного товара на свой аккаунт и убедитесь, что он появился в профиле. ## Теория Стандартная функция сравнения строк в PHP возвращает не булев результат, а **знаковое число**: ноль при равенстве, отрицательное — когда первая строка стоит по алфавиту раньше второй, положительное — когда позже. Разработчик, который проверяет «результат меньше единицы», думает, что отсекает всё, кроме равенства, — но в такую проверку проваливаются и все отрицательные результаты: любая строка, стоящая по алфавиту раньше секрета, засчитывается как совпавшая. Это ошибка чтения контракта функции, а не слабый секрет. **Уязвимый паттерн:** ```php $result = strcmp((string)$submitted, $row['secret_token']); if ($result < 1) { // равенство — это 0, но проходят и все отрицательные ``` Механика словами: проверка превращает «строки равны» в «первая строка не больше второй». Граница проходит по алфавиту, а не по совпадению: ранние символы и короткие строки почти всегда «меньше» длинного случайного секрета. Дополнительный пласт — приведение нестрокового ввода к строке: значение неожидаемого типа из формы превращается в фиксированный литерал, который тоже участвует в этом сравнении на общих основаниях. ## Точка входа атаки `POST /promo` — активация промо, поле `promo_token` (требуется CSRF-токен со страницы промо). Результат виден в списке заказов на `GET /profile`. * **Обычный пользователь:** `demo` / `demo` * **Цель:** бесплатный заказ служебного товара «CTF Flag»

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

другие лабы по этой уязвимости
Обложка лабы: Type Juggling: JSON-аутентификация с loose comparison Обложка лабы: Type Juggling: JSON-аутентификация с loose comparison
Type Jug

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

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

+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