Введение
SQL-инъекции остаются одной из самых распространённых угроз для веб-приложений. В данном запросе %'))) AND EXTRACTVALUE(7717,CONCAT(0x7e,((SELECT (ELT(7717=7717,1)))),0x7e))-- - злоумышленник пытается использовать функцию EXTRACTVALUE для извлечения данных через сообщения об ошибках. Разберём, как это работает, какие ошибки могут возникать и как защититься.
Что такое EXTRACTVALUE?
Функция EXTRACTVALUE в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_frag, XPath_expr). Однако при некорректном XPath-выражении функция возвращает ошибку, которая может содержать переданные данные. Это свойство активно используется в SQL-инъекциях для вывода информации.
Анализ запроса
Рассмотрим запрос по частям:
%')))— попытка закрыть предыдущие скобки и кавычки, чтобы внедрить свой код.AND EXTRACTVALUE(7717,CONCAT(0x7e,((SELECT (ELT(7717=7717,1)))),0x7e))— вызов функции с параметрами. Первый аргумент — число 7717 (произвольный XML), второй — конкатенация тильды (0x7e), результата подзапроса и ещё одной тильды.-- -— комментарий, отсекающий остаток оригинального запроса.
Подзапрос SELECT (ELT(7717=7717,1)) возвращает 1, так как условие истинно. ELT — функция, возвращающая N-й элемент из списка. Здесь список состоит из одного элемента 1. Таким образом, EXTRACTVALUE получает XPath-выражение вида ~1~, что не является корректным XPath, и MySQL генерирует ошибку: XPATH syntax error: '~1~'. В сообщении об ошибке отображается переданная строка, что позволяет злоумышленнику извлекать данные.
Примеры использования в атаках
Хакеры часто применяют EXTRACTVALUE для получения имён таблиц, колонок или конкретных данных. Например, заменив подзапрос на SELECT table_name FROM information_schema.tables LIMIT 1, можно получить имя первой таблицы. Ошибка покажет это имя. Аналогично можно извлечь пароли, логины и другую конфиденциальную информацию.
Ошибка 1222: разные количества колонок
В результатах поиска упоминается ошибка ERROR 1222 (21000): The used SELECT statements have a different number of columns. Она возникает при использовании UNION ALL, когда количество столбцов в объединяемых запросах не совпадает. Это классическая проблема при SQL-инъекциях через UNION. Злоумышленник должен подобрать число колонок, чтобы успешно внедрить свой SELECT. В приведённом примере с ' UNION ALL SELECT NULL,concat(0x28,username,0x3a,password,0x29) FROM users # ошибка возникла, потому что в таблице users три колонки, а в запросе указано только две (NULL и concat). Чтобы исправить, нужно добавить ещё один NULL.
Как защититься от таких инъекций
Основные меры защиты:
- Параметризованные запросы (prepared statements) — самый надёжный способ. Они разделяют код и данные, делая невозможным внедрение SQL.
- Экранирование специальных символов — используйте функции экранирования, предоставляемые драйвером БД.
- Валидация входных данных — проверяйте типы, длину, допустимые символы.
- Ограничение прав пользователя БД — не давайте приложению лишних привилегий.
- Использование ORM — современные ORM-библиотеки автоматически защищают от инъекций.
- Регулярное обновление СУБД — в новых версиях MySQL функция EXTRACTVALUE помечена как устаревшая, но в старых она опасна.
Заключение
Запрос с EXTRACTVALUE демонстрирует классическую технику error-based SQL-инъекции. Понимание таких атак помогает разработчикам и администраторам лучше защищать свои системы. Всегда используйте параметризованные запросы и следите за актуальностью версий ПО.
Комментарии
—Войдите, чтобы оставить комментарий