SQL Injection: WAF Bypass
Обход WAF с чёрным списком SQL-ключевых слов для эксплуатации SQL-инъекции в форме логина.
hardpythonPro
Задача
# SQL Injection: обход WAF на чёрном списке
## Сценарий
Перед вами Flask-приложение интернет-магазина SecureShop. Это нетипичная задача для SQLi: разработчик уже знает про класс проблемы и в форме входа добавил **дополнительный слой защиты** — самописный «WAF» на основе чёрного списка ключевых слов SQL. Перед выполнением запроса значения полей формы проверяются на наличие распространённых SQL-конструкций (`select`, `union`, `or`, `--` и т.п.); если что-то из списка найдено, запрос отвергается с заметным сообщением «Suspicious input detected!».
Идея защитить уязвимый код фильтром «опасных слов» — типичная для разработчиков, начинающих знакомиться с SQLi. На практике она не работает: количество способов выразить ту же SQL-конструкцию в обход конкретного blacklist-фильтра практически бесконечно (другой регистр, другие комментарии, разделители, кодировки, эквивалентные операторы). Любая фильтрация на чёрном списке проигрывает: достаточно одной щели — и payload проходит. И **сама исходная уязвимость никуда не исчезает** — за фильтром по-прежнему стоит обработчик, формирующий SQL-запрос строковой интерполяцией; «WAF» лишь создаёт ложное чувство защищённости.
В таблице пользователей есть привилегированная учётная запись `admin` с балансом, достаточным для покупки товара «CTF Flag» в каталоге; флаг отображается на странице профиля владельца такого заказа после оформления покупки.
## Цели
1. Подтвердите, что в форме входа значения попадают в SQL **через интерполяцию** (то есть классическая SQLi там есть), а сверху работает простой filter-by-blacklist слой («WAF»). Стандартный SQLi-payload `admin' OR 1=1 --` должен возвращать ошибку «Suspicious input detected!» — это и есть подтверждение, что фильтр на чёрном списке существует.
2. Найдите дыру в логике фильтра. Внимательно посмотрите, **как именно** значения сравниваются с чёрным списком: есть ли учёт регистра? сравнение по подстроке или по слову? есть ли альтернативные эквивалентные SQL-конструкции, не входящие в список (другой стиль комментариев, эквивалентный оператор)? Любой найденный «обход» делает SQLi доступной, потому что код за фильтром уязвим.
3. Через найденный обход войдите как `admin`, не зная пароля; купите «CTF Flag»; заберите CTF-флаг со страницы профиля.
## Данные
| Параметр | Значение |
|----------|----------|
| Обычный пользователь | `demo` / `demo` |