Что такое SQL-инъекция через EXTRACTVALUE и ELT?

SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. В данном случае рассматривается конкретный вектор, использующий функции EXTRACTVALUE и ELT для извлечения информации. Этот метод относится к классу error-based SQL-инъекций, когда атакующий заставляет базу данных вернуть данные через сообщение об ошибке.

Запрос ')))) AND EXTRACTVALUE(2443,CONCAT(0x7e,((SELECT (ELT(2443=2443,1)))),0x7e))-- - — это типичный пример эксплуатации уязвимости, где параметр ввода не фильтруется должным образом. Давайте разберём его по частям.

Разбор структуры запроса

Начнём с конца: -- - — это комментарий, который отсекает оставшуюся часть оригинального SQL-запроса. Символы ')))) закрывают ранее открытые скобки и кавычки, чтобы внедряемая конструкция стала синтаксически корректной.

Далее следует AND EXTRACTVALUE(2443, CONCAT(0x7e, ((SELECT (ELT(2443=2443,1)))), 0x7e)). Функция EXTRACTVALUE принимает два аргумента: XML-документ (или его представление) и XPath-выражение. Она возвращает значение узла, соответствующего XPath. Если XPath невалиден, генерируется ошибка, в тексте которой может содержаться результат вычисления второго аргумента.

Второй аргумент — CONCAT(0x7e, ((SELECT (ELT(2443=2443,1)))), 0x7e). CONCAT объединяет строки. 0x7e — это шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы в сообщении об ошибке было легко найти извлечённые данные. ELT — функция, возвращающая N-й элемент из списка строк. В данном случае ELT(2443=2443,1) возвращает 1, так как условие 2443=2443 истинно. Это простейший пример, демонстрирующий работу конструкции; на практике вместо 1 подставляется подзапрос, извлекающий реальные данные (например, имя пользователя, хеш пароля и т.д.).

Таким образом, при выполнении запроса база данных попытается интерпретировать строку, начинающуюся с ~, как XPath. Это вызовет ошибку, в тексте которой будет содержаться значение, возвращённое ELT. Атакующий видит его в ответе сервера.

Зачем нужен символ 0x7e?

Символ ~ (тильда) выбран не случайно. Он редко встречается в обычных данных, поэтому служит надёжным маркером начала и конца извлекаемой информации. В сообщении об ошибке, например, XPATH syntax error: '~1~', легко выделить полезную нагрузку. Если бы разделителя не было, можно было бы перепутать данные с другим текстом ошибки.

Как работает EXTRACTVALUE в MySQL

Функция EXTRACTVALUE в MySQL предназначена для работы с XML. Синтаксис: EXTRACTVALUE(xml_frag, xpath_expr). Она возвращает текст первого текстового узла, соответствующего XPath-выражению. Если XPath содержит синтаксическую ошибку, MySQL генерирует ошибку 1105 с сообщением, включающим фрагмент переданного XPath. Именно это и эксплуатируется.

Важно: начиная с MySQL 5.7.9 функция EXTRACTVALUE объявлена устаревшей, а в MySQL 8.0 удалена. Однако многие устаревшие системы всё ещё используют старые версии, поэтому угроза сохраняется.

Примеры реальных атак

Злоумышленники часто комбинируют EXTRACTVALUE с подзапросами для извлечения данных из таблиц. Например, чтобы получить имя пользователя, могут использовать:

' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT user()), 0x7e))-- -

Или для получения хеша пароля из таблицы users:

' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT password FROM users LIMIT 1), 0x7e))-- -

Если приложение выводит ошибки базы данных на экран, атакующий получит эти данные. Даже если ошибки не показываются, иногда их можно увидеть в логах или через слепые инъекции.

Меры защиты

Чтобы предотвратить такие атаки, необходимо:

  • Использовать параметризованные запросы (prepared statements) — это самый надёжный способ, при котором данные никогда не интерпретируются как SQL-код.
  • Экранировать специальные символы — если параметризация невозможна, применять функции экранирования, например mysqli_real_escape_string.
  • Отключить вывод ошибок базы данных — не показывать пользователю детали ошибок SQL.
  • Ограничить права пользователя БД — не давать приложению прав на доступ к системным таблицам и функциям.
  • Обновлять СУБД — в новых версиях MySQL опасные функции удалены или исправлены.
  • Использовать WAF — веб-приложения firewall могут блокировать подозрительные запросы.

Заключение

SQL-инъекция через EXTRACTVALUE и ELT — это серьёзная уязвимость, которая может привести к утечке конфиденциальных данных. Понимание механизма атаки помогает разработчикам правильно строить защиту. Всегда используйте параметризованные запросы и следите за обновлениями используемого программного обеспечения.

Источники