Перейти к содержимому
← Каталог golang SQL Injection

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

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

hardgolang
Задача
# SQL Injection: Обход WAF через смешанный регистр ## Сценарий Вы проводите аудит безопасности **SecureShop**. После прошлого инцидента команда разработки добавила «защиту» в виде самописного WAF: список SQL-ключевых слов (`UNION`, `SELECT`, `FROM`, `WHERE`...), и любой запрос содержащий хотя бы одно из них блокируется с сообщением «WAF Alert». Архитектор хвастался, что теперь SQLi невозможен. Однако вы помните: blacklist-подход — антипаттерн, всегда найдётся способ записать ключевое слово так, чтобы фильтр его не увидел, а парсер базы — увидел. ## Цель 1. Подтвердите наличие WAF: отправьте классический payload `' UNION SELECT 1,2,3,4,5--` через поиск каталога и убедитесь, что он блокируется. 2. Исследуйте логику фильтра — определите, чувствителен ли он к регистру. 3. Постройте payload, обходящий WAF и одновременно валидный с точки зрения SQLite (5 колонок, корректные типы). 4. Извлеките содержимое таблицы `secrets` и заберите флаг — он лежит в значении ключа `admin_api_key`. ## Теория **Blacklist-WAF** для SQLi — это попытка перечислить «опасные» строки и заблокировать их. Все такие фильтры разделяют общую слабость: между точкой проверки (приложением) и точкой выполнения (СУБД) лежит толстый слой нормализации. SQL не различает регистр ключевых слов (`SELECT` ≡ `select` ≡ `sElEcT`), допускает inline-комментарии (`UN/**/ION`), пробелы заменяются табами и переводами строк. Любое расхождение в нормализации между фильтром и парсером порождает обход. **Уязвимый паттерн:** ```go // case-sensitive blacklist — основа уязвимости: var sqlBlacklist = []string{"UNION", "SELECT", "INSERT", "FROM", "WHERE", "OR", "AND"} for _, kw := range sqlBlacklist { if strings.Contains(search, kw) { // строгое сравнение, без ToUpper http.Error(w, "WAF Alert: blocked", 400) return } } // затем тот же search без параметризации улетает в SQL: query := fmt.Sprintf("SELECT ... FROM products WHERE name LIKE '%%%s%%'", search) rows, err := h.db.Query(query) ``` В этой лабе SQL-парсер выполняет `SeLeCt`, а blacklist его не видит — классический пример асимметрии. ## Точка входа атаки * **Эндпоинт:** `GET /catalog?q=<payload>` * **Обычный пользователь:** `demo` / `demo` (для авторизации и разведки UI) > Эта лаба — наглядная иллюстрация того, почему **blacklist никогда не должен быть единственной защитой от SQLi**. Финальный фикс — параметризованные запросы, которые архитектурно разделяют код и данные.
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru