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

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

В запросе "))) AND EXTRACTVALUE(5661,CONCAT(0x7e,((SELECT (ELT(5661=5661,1)))),0x7e))-- - как раз применяется этот приём. Давайте разберём его по частям.

Анатомия вредоносного запроса

Запрос состоит из нескольких частей:

  • "))) — закрывающие скобки и кавычки, которые завершают оригинальный SQL-запрос, внедряя дополнительное условие.
  • AND EXTRACTVALUE(5661,CONCAT(0x7e,((SELECT (ELT(5661=5661,1)))),0x7e)) — вызов функции ExtractValue с двумя аргументами. Первый аргумент — произвольное число 5661, второй — строка, формируемая через CONCAT.
  • -- - — комментарий, который игнорирует остаток оригинального запроса.

Функция EXTRACTVALUE(XML, XPath) извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL выдаёт ошибку, в тексте которой отображается переданная строка. Это и есть канал утечки данных.

Как работает ELT и CONCAT

Внутри запроса используется ELT(N, str1, str2, ...) — функция, возвращающая N-ю строку из списка. В данном случае ELT(5661=5661,1) всегда возвращает 1, потому что условие 5661=5661 истинно. Это простейший пример, демонстрирующий механизм. В реальных атаках вместо этого подзапроса могут быть конструкции, извлекающие имена таблиц, колонок или хеши паролей.

CONCAT(0x7e, ..., 0x7e) объединяет символы тильды (~) с полезной нагрузкой. Тильда используется как маркер, чтобы в сообщении об ошибке было легко найти украденные данные.

Цель инъекции

Основная цель — заставить базу данных вернуть информацию в тексте ошибки. Например, злоумышленник может подставить вместо 1 подзапрос (SELECT user()), чтобы узнать текущего пользователя БД, или (SELECT password FROM users LIMIT 1), чтобы украсть пароль администратора.

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

Пример реальной эксплуатации

Взломщики часто используют error-based инъекции для дампа всей структуры базы. Например, запрос:

AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT table_name FROM information_schema.tables LIMIT 0,1), 0x7e))

выведет имя первой таблицы в базе. Меняя параметры LIMIT, можно перебрать все таблицы, затем колонки и, наконец, данные.

Как защититься от таких атак

Главный способ защиты — использование параметризованных запросов (prepared statements). Они разделяют код SQL и данные, поэтому вредоносный ввод не интерпретируется как часть команды.

  • Никогда не подставляйте пользовательские данные в SQL-запросы напрямую.
  • Используйте ORM или хранимые процедуры.
  • Ограничьте права пользователя БД: приложение должно работать с минимально необходимыми привилегиями.
  • Включите логирование и мониторинг ошибок: не показывайте детали ошибок пользователям.
  • Регулярно обновляйте СУБД и фреймворки.

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

Заключение

Запрос с ExtractValue — классический пример error-based SQL-инъекции. Понимание механики таких атак помогает разработчикам и администраторам своевременно закрывать уязвимости. Помните: безопасность — это процесс, а не разовое действие.

Источники