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

SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Среди множества техник особое место занимает error-based SQL-инъекция, когда атакующий извлекает данные через сообщения об ошибках. Функция ExtractValue в MySQL — популярный инструмент для таких атак.

Запрос, который мы разбираем: )) AND EXTRACTVALUE(6671,CONCAT(0x7e,((SELECT (ELT(6671=6671,1)))),0x7e))-- - — это классический пример error-based инъекции. Давайте разберём его по частям.

Синтаксис и логика payload

Payload состоит из нескольких вложенных функций:

  • EXTRACTVALUE(6671, ...) — функция MySQL для извлечения значения из XML-документа по XPath-выражению. Первый аргумент — XML-строка (здесь просто число 6671), второй — XPath-путь.
  • CONCAT(0x7e, ..., 0x7e) — объединяет строки. 0x7e — это шестнадцатеричное представление символа ~ (тильда), который используется как маркер начала и конца выводимых данных.
  • SELECT (ELT(6671=6671,1)) — подзапрос, возвращающий результат функции ELT. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 6671=6671 — всегда истина (1), поэтому ELT возвращает первую строку — число 1.

Внешние )) и -- - — это попытка закрыть скобки оригинального запроса и закомментировать остаток строки, чтобы внедрённый код выполнился корректно.

Почему возникает ошибка XPATH?

Функция EXTRACTVALUE ожидает, что второй аргумент будет корректным XPath-выражением. В нашем случае туда передаётся строка, начинающаяся с символа ~, что не является валидным XPath. MySQL генерирует ошибку:

ERROR 1105 (HY000): XPATH syntax error: '~1~'

Именно это и нужно атакующему: в тексте ошибки отображается результат выполнения вложенного подзапроса — в данном случае ~1~. Меняя подзапрос, злоумышленник может извлекать имена таблиц, колонок, пароли и другие данные.

Как это работает на практике

Обычно атака строится так:

  1. Находят уязвимый параметр, например id=1 в URL.
  2. Внедряют payload, который вызывает ошибку с полезной нагрузкой.
  3. Анализируют сообщение об ошибке, извлекая данные.

Пример для получения имени базы данных:

AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))

В ответе появится ошибка вида XPATH syntax error: '~mydb~'.

Защита от error-based SQL-инъекций

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

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

Важно понимать, что ExtractValue — не единственная функция, используемая в error-based атаках. Аналогично работают UpdateXML, GTID_SUBSET и другие.

Заключение

Разобранный payload — наглядный пример эксплуатации ошибок MySQL для извлечения данных. Понимание механики таких атак помогает разработчикам и администраторам лучше защищать свои приложения. Всегда используйте подготовленные выражения и следите за обновлениями безопасности.

Источники