Что такое error-based SQL-инъекция через EXTRACTVALUE?
Error-based SQL-инъекция — это метод атаки на базы данных, при котором злоумышленник извлекает информацию, заставляя СУБД возвращать данные в сообщениях об ошибках. В MySQL одной из самых популярных функций для этого является EXTRACTVALUE() — функция для работы с XML, которая генерирует ошибку, если переданный XPath-выражение некорректно. Атакующий подставляет в уязвимый параметр специально сконструированную строку, и в тексте ошибки MySQL отображает результат выполнения вложенного подзапроса.
Пример, который часто встречается в отчётах пентестеров и на учебных платформах (например, DVWA), выглядит так:
%'))) AND EXTRACTVALUE(1919,CONCAT(0x7e,((SELECT (ELT(1919=1919,1)))),0x7e))-- -
Эта строка — классический пример error-based SQL-инъекции. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке.
Как работает этот запрос?
Разберём по частям:
- %'))) — часть, которая «ломает» оригинальный SQL-запрос, закрывая кавычки и скобки, чтобы внедрить свой код.
- AND EXTRACTVALUE(1919, CONCAT(0x7e, ((SELECT (ELT(1919=1919,1)))), 0x7e)) — вызов функции EXTRACTVALUE. Первый аргумент (1919) — произвольное число, второй — XPath-выражение, которое формируется через CONCAT. Символ 0x7e — это тильда (~), используется как разделитель, чтобы результат было легко найти в тексте ошибки.
- ELT(1919=1919,1) — функция ELT возвращает N-й элемент из списка. Здесь 1919=1919 — всегда истина (1), поэтому ELT(1,1) вернёт 1. Это простейший пример; на практике вместо этого подзапроса внедряют SELECT для получения имён таблиц, колонок или паролей.
- -- - — комментарий, который обрезает оставшуюся часть оригинального запроса.
Когда MySQL выполняет EXTRACTVALUE с некорректным XPath (а CONCAT создаёт строку вроде ~1~, что не является валидным XPath), генерируется ошибка вида: XPATH syntax error: '~1~'. В этом сообщении и оказывается результат подзапроса.
Зачем нужна такая инъекция?
Error-based инъекции применяются, когда другие методы (UNION, blind) недоступны или неудобны. Они позволяют быстро получить данные, если веб-приложение выводит ошибки СУБД на страницу. Основные сценарии:
- Извлечение версии MySQL, имени базы, пользователя.
- Получение имён таблиц и колонок из information_schema.
- Чтение конкретных данных (логины, пароли, номера карт).
Для этого вместо ELT(1919=1919,1) подставляют подзапрос, например: (SELECT table_name FROM information_schema.tables LIMIT 0,1). Результат также попадёт в ошибку.
Пример практического использования
Предположим, есть уязвимый параметр id в URL: http://site.com/product.php?id=1. Атакующий может отправить:
1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))
В ответе сервера появится ошибка с именем текущей базы данных. Это демонстрирует опасность отсутствия фильтрации входных данных.
Меры защиты
Чтобы предотвратить error-based SQL-инъекции, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией запросов. Это самый надёжный способ.
- Экранировать специальные символы с помощью функций вроде mysqli_real_escape_string (для MySQL).
- Отключить вывод ошибок СУБД в production-окружении. Ошибки должны логироваться, а не показываться пользователю.
- Применять принцип наименьших привилегий для учётной записи БД: не давать прав на чтение information_schema без необходимости.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Важно понимать, что EXTRACTVALUE — не единственная функция для error-based инъекций. Также используются UPDATEXML, GTID_SUBSET, EXP и другие. Однако EXTRACTVALUE остаётся популярной из-за простоты и наглядности.
Заключение
Строка %'))) AND EXTRACTVALUE(1919,CONCAT(0x7e,((SELECT (ELT(1919=1919,1)))),0x7e))-- - — это учебный пример эксплуатации error-based SQL-инъекции в MySQL. Она показывает, как через функцию EXTRACTVALUE можно вытащить данные из базы, используя сообщения об ошибках. Понимание этой техники необходимо как пентестерам, так и разработчикам для написания безопасного кода. Всегда проверяйте входные данные и используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий