Введение
Встречая в логах или в параметрах URL строку вида ') OR ExtractValue(9694, Concat(0x7e,((Select (Elt(9694=9694,1)))),0x7e))-- -, многие задаются вопросом: что это такое? Это не случайный набор символов, а классический пример SQL-инъекции (SQL injection), направленной на извлечение данных из базы данных MySQL через механизм ошибок. В данной статье мы подробно разберём, как работает этот запрос, какие функции задействованы и как защититься от подобных атак.
Что такое SQL-инъекция?
SQL-инъекция — один из самых распространённых способов взлома веб-приложений. Злоумышленник внедряет вредоносный SQL-код в входные данные (формы, параметры URL, cookies), которые затем попадают в SQL-запрос без должной обработки. Если приложение уязвимо, база данных выполнит этот код, что может привести к утечке конфиденциальной информации, модификации или удалению данных.
Существует несколько типов SQL-инъекций: Union-based, Boolean-based, Time-based и Error-based. Рассматриваемый запрос относится к последнему типу — error-based SQL injection.
Разбор запроса по частям
Давайте разберём строку ') OR ExtractValue(9694, Concat(0x7e,((Select (Elt(9694=9694,1)))),0x7e))-- - на составные элементы.
1. Закрывающая кавычка и скобка
Начинается всё с '). Это попытка закрыть ранее открытую скобку и строковый литерал в оригинальном запросе. Например, если уязвимый запрос выглядел как SELECT * FROM users WHERE name = ('$input'), то подстановка ') разрывает строку и позволяет добавить произвольный SQL-код.
2. Оператор OR
Далее идёт OR. Это логический оператор, который делает условие всегда истинным, если правая часть верна. Внедряющий код стремится к тому, чтобы запрос вернул данные или вызвал ошибку, которую можно проанализировать.
3. Функция ExtractValue
ExtractValue() — это встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: ExtractValue(xml_frag, xpath_expr). Она возвращает текст первого узла, соответствующего XPath. Однако если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой может содержаться переданный фрагмент. Именно это и используется для error-based инъекции.
4. Аргументы функции
В нашем случае первый аргумент — 9694 (произвольное число, может быть любым). Второй аргумент — Concat(0x7e,((Select (Elt(9694=9694,1)))),0x7e).
0x7e— шестнадцатеричное представление символа тильды (~). Часто используется как разделитель, чтобы облегчить извлечение данных из сообщения об ошибке.Elt(9694=9694,1)— функцияELT()возвращает N-й элемент из списка. Здесь9694=9694— это логическое выражение, которое всегда истинно (1). ФактическиELT(1,1)вернёт1. Это простейшая проверка, демонстрирующая работу инъекции. В реальной атаке вместо этого подзапроса мог бы быть(SELECT user FROM users LIMIT 1)или другой запрос, извлекающий конфиденциальные данные.Concatобъединяет тильду, результат подзапроса и ещё одну тильду. Получается строка вида~1~.
5. Комментарий в конце
-- - — это комментарий в SQL. Всё, что идёт после него, игнорируется базой данных. Это позволяет отсечь остаток оригинального запроса, который мог бы вызвать синтаксическую ошибку.
Как работает атака
Когда уязвимое приложение подставляет эту строку в SQL-запрос, итоговый запрос может выглядеть так:
SELECT * FROM products WHERE id = ('') OR ExtractValue(9694, Concat(0x7e,((SELECT (ELT(9694=9694,1)))),0x7e))-- -')
База данных выполняет ExtractValue с некорректным XPath (поскольку ~1~ не является допустимым XPath). MySQL выдаёт ошибку примерно такого содержания:
XPATH syntax error: '~1~'
Эта ошибка возвращается приложению (если оно выводит ошибки БД), и атакующий видит результат выполнения подзапроса. Заменив ELT(9694=9694,1) на другой подзапрос, злоумышленник может посимвольно извлекать имена таблиц, колонок, логины и пароли пользователей.
Почему это опасно?
Error-based инъекции опасны тем, что позволяют получать данные напрямую в сообщениях об ошибках, без необходимости слепого перебора. Если приложение настроено на вывод ошибок MySQL, атакующий быстро получит структуру БД и содержимое таблиц. В случае с ExtractValue ограничение на длину вывода (около 32 символов) заставляет использовать посимвольное извлечение, но это лишь замедляет атаку.
Как защититься
Основной метод защиты — использование параметризованных запросов (prepared statements). Никогда не подставляйте пользовательские данные в SQL-запросы напрямую. Дополнительные меры:
- Отключите вывод подробных ошибок БД в production-окружении.
- Используйте ORM или хранимые процедуры с параметрами.
- Проводите регулярный аудит кода и сканирование уязвимостей.
- Применяйте принцип наименьших привилегий для пользователя БД.
Заключение
Строка ') OR ExtractValue(9694, Concat(0x7e,((Select (Elt(9694=9694,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции через функцию ExtractValue. Она демонстрирует, как злоумышленники могут использовать особенности MySQL для извлечения данных. Понимание таких атак помогает разработчикам и администраторам лучше защищать свои системы.
Комментарии
—Войдите, чтобы оставить комментарий