Введение
SQL-инъекции остаются одной из самых распространённых угроз для веб-приложений. Особое место среди них занимают error-based инъекции, при которых злоумышленник извлекает данные из базы через сообщения об ошибках. Запрос ' AND EXTRACTVALUE(5446,CONCAT(0x7e,((SELECT (ELT(5446=5446,1)))),0x7e))-- - — классический пример такой атаки. В этой статье мы разберём, как он устроен, какие функции MySQL задействованы и как защититься.
Что такое error-based SQL-инъекция?
Error-based SQL-инъекция — это метод эксплуатации уязвимости, при котором атакующий заставляет базу данных выдать конфиденциальную информацию в тексте ошибки. В отличие от UNION-инъекций, здесь не требуется совпадения количества столбцов, а результат извлекается через намеренно вызванные ошибки.
В MySQL для этого часто используют функции EXTRACTVALUE и UPDATEXML. Они генерируют ошибку, если переданный XML-фрагмент некорректен, и в сообщении об ошибке отображается переданная строка.
Разбор запроса по частям
Рассмотрим внедряемую строку подробнее:
' AND EXTRACTVALUE(5446,CONCAT(0x7e,((SELECT (ELT(5446=5446,1)))),0x7e))-- -
- ' — закрывает строковый литерал в исходном запросе, делая дальнейший код частью SQL-выражения.
- AND — логический оператор, присоединяющий условие к WHERE.
- EXTRACTVALUE(5446, ...) — функция MySQL, извлекающая значение из XML. Первый аргумент (5446) — произвольное число, которое не является корректным XML, что гарантирует ошибку.
- CONCAT(0x7e, ..., 0x7e) — объединяет символ ~ (0x7e) с полезной нагрузкой, чтобы отделить результат в сообщении об ошибке.
- (SELECT (ELT(5446=5446,1))) — подзапрос, возвращающий 1. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь условие 5446=5446 всегда истинно, поэтому ELT(1,1) вернёт 1. Это простейшая проверка работоспособности инъекции.
- -- - — комментарий, обрезающий остаток оригинального запроса.
В результате MySQL попытается обработать строку ~1~ как XML и выдаст ошибку вида: XPATH syntax error: '~1~'. Это подтверждает, что инъекция возможна.
Зачем нужны EXTRACTVALUE и ELT?
Функция EXTRACTVALUE(XML, XPath) извлекает данные по XPath-выражению. Если первый аргумент не является валидным XML, MySQL возвращает ошибку с указанием проблемного фрагмента. Это позволяет выводить произвольные данные, подставляя их в XPath.
Функция ELT(N, str1, str2, ...) возвращает N-й элемент списка. В контексте инъекции она используется для формирования строки, которая затем попадёт в ошибку. В нашем примере ELT(5446=5446,1) возвращает 1, так как условие истинно (1).
Комбинация этих функций позволяет атакующему постепенно извлекать имена таблиц, столбцов и сами данные, подставляя вместо 1 подзапросы, например: SELECT table_name FROM information_schema.tables LIMIT 0,1.
Пошаговый пример эксплуатации
Предположим, есть уязвимый параметр id в URL. Атакующий может отправить:
1' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database()),0x7e))-- -
В ответе придёт ошибка с именем текущей базы данных. Затем можно извлекать таблицы:
1' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1),0x7e))-- -
И так далее, пока не будут получены все нужные сведения. Ограничение в 32 символа (для некоторых версий MySQL) обходится использованием SUBSTRING.
Меры защиты
Лучший способ предотвратить такие атаки — использовать параметризованные запросы (prepared statements). Они разделяют код и данные, поэтому внедрение SQL-кода становится невозможным.
- Параметризация запросов — основной метод.
- Экранирование специальных символов — вспомогательная мера, но не панацея.
- Валидация входных данных — проверка типов, белые списки.
- Минимизация привилегий СУБД — учётная запись приложения не должна иметь прав на чтение information_schema и системных таблиц.
- Использование ORM — современные ORM автоматически параметризуют запросы.
- Регулярные сканирования уязвимостей — например, с помощью SQLMap.
Также рекомендуется отключить вывод подробных ошибок MySQL на продакшене, чтобы атакующий не получал подсказок.
Заключение
Запрос ' AND EXTRACTVALUE(5446,CONCAT(0x7e,((SELECT (ELT(5446=5446,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции, использующей особенности функций MySQL. Понимание механики таких атак помогает разработчикам и специалистам по безопасности правильно выстраивать защиту. Помните: безопасность — это процесс, а не одноразовое действие.
Комментарии
—Войдите, чтобы оставить комментарий