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

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

SQL Injection: Обход WAF через mixed case

Case-sensitive blacklist SQL keywords обходится через смешанный регистр (uNiOn, sElEcT)

Автор: Hack & Fix
Освоишь: параметризованные запросыprepared statementsleast-privilege DB
Сложно+90 XP ~65 мин golang
CWE-89 · A03:2021
Обложка: SQL Injection: Обход WAF через mixed case Обложка: SQL Injection: Обход WAF через mixed case
Задача
# SQL-инъекция: обход самодельного WAF через регистр ## Сценарий Вы проводите аудит безопасности **PhantomSupply** — магазина снаряжения для команд тестирования на проникновение. После прошлого инцидента команда вшила в поиск каталога «WAF»: список SQL-ключевых слов верхнего регистра, и любая фраза с ними блокируется предупреждением. Архитектор уверен, что SQL-инъекции теперь невозможны. Вы знаете антипаттерн: чёрный список перечисляет «опасные» строки, а между фильтром и парсером базы всегда найдётся расхождение. ## Цель 1. Подтвердите работу фильтра: поисковые фразы с обычными SQL-ключевыми словами блокируются предупреждением. 2. Изучите логику фильтра и найдите его слепую зону — свойство записи ключевых слов, которое фильтр не учитывает. 3. Составьте поисковую фразу, которая не задевает фильтр, но исполняется базой как SQL-команда, и подберите структуру присоединяемой выборки под запрос каталога. 4. Извлеките секретный ключ администратора из скрытой таблицы — он и есть флаг лабы. ## Теория **Чёрный список ключевых слов** — попытка перечислить «опасные» строки и заблокировать их. Общая слабость всех таких фильтров: между точкой проверки (приложение) и точкой исполнения (СУБД) лежит слой нормализации. SQL не различает регистр ключевых слов, а побайтовое сравнение подстрок — различает. Любое расхождение в нормализации между фильтром и парсером порождает обход. **Уязвимый паттерн:** ```go // Фильтр ищет ключевые слова верхнего регистра побайтовым сравнением: if strings.Contains(search, keyword) { /* блокировка с предупреждением */ } // ...а затем та же фраза собирается в SQL форматированием строки: query := fmt.Sprintf("SELECT id, name, description, price, image FROM products WHERE name LIKE '%%%s%%'", search) ``` Пока ключевое слово записано точно в том виде, в каком оно хранится в списке, запрос блокируется. Но база исполняет ключевые слова в любом регистре — и вариант, записанный иначе, фильтр не замечает, а парсер послушно выполняет. Фильтр задерживает только «вежливых» атакующих, а сама инъекция живёт в конкатенации фразы в текст запроса. ## Точка входа атаки `GET /catalog` — поиск по каталогу, поле `q`. * **Обычный пользователь:** `demo` / `demo` > Лаба — наглядная демонстрация, почему чёрный список не должен быть единственной защитой от SQL-инъекций: финальное исправление — разделение SQL-кода и данных, а не более длинный список слов.

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

другие лабы по этой уязвимости
Обложка лабы: Blind Boolean SQL Injection Обложка лабы: Blind Boolean SQL Injection
SQLi

Blind Boolean SQL Injection

Слепая Boolean-based SQL-инъекция через Cookie купона

+90 XP
Go FREE
Exploit Fix
Обложка лабы: Time-Based Blind SQL Injection Обложка лабы: Time-Based Blind SQL Injection
SQLi

Time-Based Blind SQL Injection

Эксплуатация слепой SQL-инъекции, основанной на задержках времени ответа (Time-Based) в SQLite.

+90 XP
Go FREE
Exploit Fix
Обложка лабы: SQL Injection: Second-Order (хранимая инъекция) Обложка лабы: SQL Injection: Second-Order (хранимая инъекция)
SQLi

SQL Injection: Second-Order (хранимая инъекция)

Payload сохраняется в БД через безопасный INSERT, но выполняется в другом запросе через конкатенацию строк

+90 XP
Go FREE
Exploit Fix
Обложка лабы: Union-Based SQL Injection Обложка лабы: Union-Based SQL Injection
SQLi

Union-Based SQL Injection

Получение пароля администратора с использованием UNION SELECT

+60 XP
Go FREE
Exploit Fix