Что это за запрос?
Строка OR EXTRACTVALUE(2589,CONCAT(0x7e,((SELECT (ELT(2589=2589,1)))),0x7e))-- - — это классический пример SQL-инъекции, предназначенной для извлечения данных из базы данных через механизм ошибок. Подобные конструкции часто встречаются в отчётах сканеров уязвимостей и в эксплойтах для MySQL. Давайте разберём её по частям.
Как работает инъекция
Запрос начинается с OR, что позволяет обойти условие в исходном SQL-запросе (например, WHERE id = 1) и сделать его всегда истинным. Далее вызывается функция EXTRACTVALUE — встроенная функция MySQL (и MariaDB), предназначенная для работы с XML. Она принимает два аргумента: XML-документ и XPath-выражение, и возвращает скалярное значение из узла.
Второй аргумент формируется с помощью CONCAT(0x7e, ((SELECT (ELT(2589=2589,1)))), 0x7e). Здесь 0x7e — это шестнадцатеричное представление символа ~ (тильда). Функция CONCAT склеивает тильду, результат подзапроса и ещё одну тильду. Подзапрос SELECT (ELT(2589=2589,1)) использует функцию ELT, которая возвращает N-й элемент из списка. В данном случае 2589=2589 — всегда истинно (1), поэтому ELT(1,1) вернёт 1. Однако в реальной атаке вместо 1 мог бы быть результат другого выражения, например, имя пользователя или хеш пароля.
Ключевой момент: EXTRACTVALUE ожидает, что XPath-выражение будет корректным. Если оно содержит символ, недопустимый в XPath (например, тильду), функция генерирует ошибку, в тексте которой выводится переданное значение. Таким образом, злоумышленник может заставить сервер вернуть нужные данные в сообщении об ошибке.
Зачем нужен -- -
Символы -- начинают комментарий в SQL (в MySQL требуется пробел после двух дефисов, поэтому часто пишут -- -). Это позволяет «отрезать» оставшуюся часть исходного запроса, чтобы синтаксис оставался корректным. Например, если исходный запрос был SELECT * FROM users WHERE id = 1, после подстановки пользовательского ввода может получиться SELECT * FROM users WHERE id = 1 OR EXTRACTVALUE(...) -- -.
Почему это опасно
Эксплуатация подобной уязвимости позволяет атакующему извлекать произвольные данные из базы: имена таблиц, логины, пароли, номера кредитных карт и т.д. Инъекции на основе ошибок (error-based SQL injection) особенно эффективны, когда приложение выводит сообщения об ошибках базы данных пользователю. Даже если вывод ошибок отключён, злоумышленник может использовать слепые методы, но в данном случае конструкция явно рассчитана на получение данных через текст ошибки.
Как защититься
Основной способ защиты — использование параметризованных запросов (prepared statements). В этом случае пользовательский ввод никогда не интерпретируется как часть SQL-кода. Дополнительные меры:
- Отключить вывод ошибок базы данных в production-окружении.
- Использовать ORM или query builder с экранированием.
- Проводить регулярное сканирование кода на уязвимости.
- Ограничить права пользователя базы данных, чтобы даже при инъекции нельзя было прочитать лишние таблицы.
Также рекомендуется валидировать входящие данные на соответствие ожидаемому формату (например, только цифры для ID).
Технические детали
Функция EXTRACTVALUE в MySQL имеет следующий синтаксис: EXTRACTVALUE(xml_frag, xpath_expr). Если XPath-выражение содержит недопустимые символы, MySQL возвращает ошибку вида: XPATH syntax error: '~1~'. Именно это и используется для извлечения данных. В приведённом запросе тильды служат маркерами, чтобы облегчить парсинг результата. Функция ELT возвращает строку по её номеру из списка аргументов: ELT(N, str1, str2, ...). В нашем случае ELT(2589=2589,1) — это ELT(1,1), что даёт 1. Если бы условие было ложным, вернулся бы 0 (или NULL, если N вне диапазона).
Стоит отметить, что в современных версиях MySQL функция EXTRACTVALUE считается устаревшей (deprecated), но продолжает работать. В MariaDB она также присутствует. Для аналогичных целей существуют UPDATEXML и другие функции, которые тоже могут быть использованы в error-based инъекциях.
Заключение
Рассмотренная конструкция — типичный пример эксплуатации ошибок в SQL-запросах для получения данных. Понимание механизма работы таких инъекций помогает разработчикам и специалистам по безопасности правильно выстраивать защиту. Никогда не подставляйте пользовательский ввод напрямую в SQL-запросы и следите за обновлениями используемого программного обеспечения.
Комментарии
—Войдите, чтобы оставить комментарий