Введение
SQL-инъекции остаются одной из самых распространённых уязвимостей веб-приложений. Среди них особое место занимают error-based инъекции, позволяющие извлекать данные через сообщения об ошибках. Одним из классических приёмов является использование функции ExtractValue в MySQL. В этой статье мы детально разберём конкретный запрос, который выглядит как:
")) AND EXTRACTVALUE(3126,CONCAT(0x7e,((SELECT (ELT(3126=3126,1)))),0x7e))-- -
Этот запрос — пример эксплуатации уязвимости, когда злоумышленник пытается вызвать ошибку XPath, содержащую результат подзапроса. Мы объясним, как это работает, какие механизмы задействованы и как защититься.
Что такое ExtractValue и XPATH-инъекции
Функция EXTRACTVALUE(XML_document, XPath_expression) в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Если XPath-выражение синтаксически некорректно, MySQL генерирует ошибку, включающую часть этого выражения. Это свойство активно используется для error-based SQL-инъекций: злоумышленник конструирует XPath, который вызывает ошибку, и в тексте ошибки выводится полезная информация (например, версия БД, имена таблиц, данные).
Подобный подход известен как XPATH injection. Он был обнаружен в ходе пентестов и описан в специализированной литературе. Например, в одном из отчётов приводится пример, когда ошибка вида ERROR 1105 (HY000): XPATH syntax error: ':1' позволяет извлечь данные.
Разбор конкретного запроса
Рассмотрим запрос по частям:
"))— закрытие предыдущих конструкций. В контексте уязвимого параметра это может завершать строковый литерал и блок кода, чтобы внедрить свой SQL.AND EXTRACTVALUE(3126, CONCAT(0x7e, ((SELECT (ELT(3126=3126,1)))), 0x7e))— основная полезная нагрузка.-- -— комментарий, отсекающий оставшуюся часть оригинального запроса.
Внутри EXTRACTVALUE первым аргументом идёт число 3126 — это произвольный XML-документ (фактически невалидный, но это не важно). Второй аргумент — XPath-выражение, которое строится так:
CONCAT(0x7e, ((SELECT (ELT(3126=3126,1)))), 0x7e)— объединяет тильды (~, код 0x7e) с результатом подзапроса.ELT(3126=3126,1)— функцияELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь3126=3126— это логическое выражение, которое всегда истинно (1). Таким образом,ELT(1,1)вернёт1. Это простейший пример, демонстрирующий возможность подстановки произвольного выражения.
В результате XPath-выражение становится ~1~. Функция EXTRACTVALUE попытается интерпретировать это как XPath и выдаст ошибку, например: XPATH syntax error: '~1~'. В тексте ошибки появится значение, возвращённое подзапросом. В данном случае это просто 1, но на месте ELT может быть любой другой запрос, извлекающий данные (например, версию БД, имена таблиц).
Зачем это нужно злоумышленнику
Основная цель — получить информацию о базе данных через сообщения об ошибках, когда другие методы (union-based, blind) недоступны. Error-based инъекции позволяют быстро извлекать данные, так как не требуют множественных запросов для проверки условий. В примере с ELT(3126=3126,1) демонстрируется сама возможность внедрения, но на практике вместо 1 подставляют подзапросы, например:
AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))
Это выведет версию MySQL в ошибке.
Примеры из реальных пентестов
В одном из отчётов приводится запрос, который дампит первую колонку таблицы username:
+AND+ (SELECT+1+FROM+ (SELECT+COUNT (*),CONCAT ((SELECT (SELECT+CONCAT (CAST (column_name+AS+CHAR),0x7e))+FROM+INFORMATION_SCHEMA.COLUMNS+WHERE+table_name=0x757365726e616d65+AND+table_schema=0x6c69746f666c6578+LIMIT 0,1),FLOOR (RAND (0)*2))x+FROM+INFORMATION ...
Здесь используется комбинация COUNT, CONCAT, FLOOR(RAND(0)*2) для генерации ошибки, но суть та же — вытащить данные через сообщение об ошибке.
Как защититься от таких атак
Основные меры:
- Параметризованные запросы (prepared statements) — самый надёжный способ. Они разделяют код и данные, поэтому внедрение SQL невозможно.
- Экранирование специальных символов — если параметризация недоступна, используйте функции экранирования (например,
mysqli_real_escape_string). - Валидация входных данных — проверяйте типы, форматы, отбрасывайте подозрительные символы.
- Минимизация привилегий СУБД — учётная запись приложения не должна иметь прав на чтение системных таблиц, если это не требуется.
- Отключение вывода ошибок на продакшене — сообщения об ошибках не должны показываться пользователю, чтобы не давать подсказок злоумышленнику.
Также рекомендуется использовать Web Application Firewall (WAF) для фильтрации подозрительных запросов, но это не замена правильному кодированию.
Заключение
Запрос ")) AND EXTRACTVALUE(3126,CONCAT(0x7e,((SELECT (ELT(3126=3126,1)))),0x7e))-- - — типичный пример error-based SQL-инъекции через функцию EXTRACTVALUE. Он демонстрирует, как можно вызвать ошибку XPath, содержащую результат подзапроса. Понимание таких техник необходимо для разработки безопасных приложений. Всегда используйте параметризованные запросы и не выводите ошибки СУБД пользователю.
Комментарии
—Войдите, чтобы оставить комментарий