Введение в SQL-инъекции через ошибки
SQL-инъекции остаются одной из самых распространённых уязвимостей веб-приложений. Среди них особое место занимают error-based инъекции, при которых злоумышленник извлекает данные, заставляя базу данных возвращать сообщения об ошибках, содержащие конфиденциальную информацию. Запрос `) AND EXTRACTVALUE(1403,CONCAT(0x7e,((SELECT (ELT(1403=1403,1)))),0x7e))-- - — классический пример такой атаки, нацеленной на MySQL.
Что такое EXTRACTVALUE?
EXTRACTVALUE — это встроенная функция MySQL, предназначенная для извлечения значения из фрагмента XML. Синтаксис: EXTRACTVALUE(XML_frag, XPath_expr). Она принимает XML-документ и выражение XPath, возвращая строку с результатом. Однако при некорректном XPath-выражении функция генерирует ошибку XPATH syntax error, которая включает в себя переданный фрагмент. Именно это свойство эксплуатируется в error-based SQL-инъекциях.
Впервые техника была описана в 2012 году исследователем безопасности, и с тех пор стала стандартным инструментом пентестеров. Аналогичные функции: UPDATEXML и GTID_SUBSET.
Разбор внедряемого запроса
Рассмотрим payload по частям:
`) AND ... -- -— закрывает предыдущее выражение в SQL-запросе приложения. Символы)и`завершают открытые скобку и обратный апостроф, а-- -комментирует остаток оригинального запроса.EXTRACTVALUE(1403, CONCAT(0x7e, ((SELECT (ELT(1403=1403,1)))), 0x7e))— основная часть. Первый аргумент1403— произвольное число, которое будет интерпретировано как XML-фрагмент (не является корректным XML). Второй аргумент — строка, начинающаяся и заканчивающаяся символом~(0x7e).CONCAT(0x7e, ((SELECT (ELT(1403=1403,1)))), 0x7e)— конкатенация тильды, результата подзапроса и ещё одной тильды. ПодзапросSELECT (ELT(1403=1403,1))возвращает 1, так как условие1403=1403истинно. ELT(N, str1, str2, ...) возвращает N-ю строку из списка; здесь список состоит из одного элемента 1.
В итоге EXTRACTVALUE получает на вход число 1403 (не XML) и строку ~1~. Поскольку 1403 не является валидным XML, MySQL выдаёт ошибку: XPATH syntax error: '~1~'. В реальной атаке вместо 1 подставляется выражение, извлекающее данные (например, имя пользователя, хеш пароля), и оно отображается в тексте ошибки.
Как работает эксплойт на практике
Предположим, уязвимый запрос выглядит так: SELECT * FROM users WHERE id = '$id'. Злоумышленник передаёт в параметр id строку:
1') AND EXTRACTVALUE(1403,CONCAT(0x7e,(SELECT database()),0x7e))-- -
Тогда итоговый SQL-запрос становится:
SELECT * FROM users WHERE id = '1') AND EXTRACTVALUE(1403,CONCAT(0x7e,(SELECT database()),0x7e))-- -'
База данных выполняет подзапрос, получает имя текущей базы (например, shop_db), формирует строку ~shop_db~, и EXTRACTVALUE генерирует ошибку с этим текстом. Приложение выводит ошибку на экран, и атакующий видит имя базы. Аналогично можно извлечь таблицы, столбцы, логины и пароли.
Почему используется CONCAT и ELT?
CONCAT нужен для объединения разделителей (тильд) с полезной нагрузкой, чтобы чётко выделить извлекаемые данные в сообщении об ошибке. Тильда выбрана как редко встречающийся символ, который легко найти в тексте ошибки.
ELT (Extract List of Terms) — функция, возвращающая N-й элемент из списка строк. В данном случае она используется для генерации константного значения 1, чтобы продемонстрировать работоспособность инъекции. В реальных атаках вместо ELT могут применяться другие функции, например CONCAT_WS или GROUP_CONCAT для объединения нескольких значений.
Последствия для безопасности
Успешная эксплуатация такой инъекции позволяет злоумышленнику:
- Получить доступ ко всем данным в базе: учётные записи, персональные данные, платёжная информация.
- Изменять или удалять информацию.
- Выполнять административные операции, если уязвимый пользователь БД обладает высокими привилегиями.
- В некоторых случаях — выполнять команды на сервере через
LOAD_FILEилиINTO OUTFILE.
По данным OWASP, инъекции занимают третье место в топ-10 критических угроз веб-приложений (2021).
Как защититься от error-based SQL-инъекций
Основной метод — использование параметризованных запросов (prepared statements). Они отделяют код SQL от данных, делая невозможным внедрение произвольных конструкций. Даже если злоумышленник передаст вредоносную строку, она будет обработана как литерал, а не как часть запроса.
Дополнительные меры:
- Отключите вывод подробных ошибок БД в production-среде. Пользователь должен видеть общее сообщение, а детали записываться в лог.
- Используйте хранимые процедуры с параметрами.
- Ограничьте привилегии пользователя БД, от имени которого работает приложение (только необходимые операции).
- Применяйте WAF (Web Application Firewall) для фильтрации подозрительных запросов.
- Регулярно обновляйте СУБД и фреймворки.
Заключение
Запрос `) AND EXTRACTVALUE(1403,CONCAT(0x7e,((SELECT (ELT(1403=1403,1)))),0x7e))-- - — это не просто набор символов, а рабочий эксплойт для извлечения данных через ошибки MySQL. Понимание его механики помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Помните: лучшая защита — параметризация запросов и минимизация вывода ошибок.
Комментарии
—Войдите, чтобы оставить комментарий