Что это за строка?

Запрос вида " OR EXTRACTVALUE(7619,CONCAT(0x7e,((SELECT (ELT(7619=7619,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через сообщения об ошибках, которые возвращает сервер.

Подобные строки часто встречаются в логах веб-серверов, в отчётах сканеров уязвимостей или в попытках взлома. Если вы увидели её в своих логах — значит, кто-то пытался протестировать ваш сайт на наличие SQL-инъекций.

Как работает EXTRACTVALUE?

Функция EXTRACTVALUE() в MySQL принимает два строковых аргумента: фрагмент XML-разметки и выражение XPath (локатор). Она возвращает текст (CDATA) первого текстового узла, который является дочерним для элемента или элементов, соответствующих выражению XPath.

Пример корректного использования:

SELECT EXTRACTVALUE('<a>текст</a>', '/a');
-- Вернёт: текст

Однако если XPath-выражение некорректно, MySQL генерирует ошибку. Злоумышленники пользуются этим, чтобы заставить сервер вывести в сообщении об ошибке нужные данные.

Разбор конкретной инъекции

Рассмотрим по частям строку " OR EXTRACTVALUE(7619,CONCAT(0x7e,((SELECT (ELT(7619=7619,1)))),0x7e))-- -.

  • " — закрывает строковый литерал в уязвимом запросе, чтобы далее можно было добавить произвольный SQL-код.
  • OR — логический оператор, который делает условие всегда истинным (если правая часть верна).
  • EXTRACTVALUE(7619, ...) — первый аргумент — произвольное число (может быть любым), второй — XPath-выражение, которое вызывает ошибку.
  • CONCAT(0x7e, ..., 0x7e) — объединяет символ ~ (0x7e) с результатом подзапроса. Символ ~ используется как маркер, чтобы потом легко найти данные в тексте ошибки.
  • SELECT (ELT(7619=7619,1)) — подзапрос, который возвращает 1, если условие 7619=7619 истинно. Это простейшая проверка, которая всегда истинна. В реальных атаках вместо этого подзапроса извлекаются имена таблиц, колонок или хеши паролей.
  • -- - — комментарий, который отсекает оставшуюся часть оригинального запроса.

В результате MySQL пытается выполнить XPath-выражение, которое не является корректным (например, из-за символа ~), и возвращает ошибку вида: XPATH syntax error: '~1~'. В этом сообщении и «утекают» данные, полученные из подзапроса.

Зачем это нужно злоумышленнику?

Error-based SQL-инъекции позволяют извлекать информацию из базы данных посимвольно или целыми строками, используя сообщения об ошибках как канал передачи данных. Это один из самых быстрых и удобных методов, когда приложение выводит ошибки СУБД на страницу.

С помощью таких инъекций можно получить:

  • имена таблиц и колонок;
  • учётные данные пользователей (логины, хеши паролей);
  • номера кредитных карт, персональные данные;
  • информацию о версии СУБД и текущем пользователе.

Как защититься?

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

Дополнительные меры:

  1. Отключите вывод ошибок СУБД в production-окружении. Ошибки должны логироваться, но не показываться пользователю.
  2. Используйте ORM или библиотеки, которые автоматически экранируют данные.
  3. Проводите регулярные сканирования уязвимостей и аудиты кода.
  4. Применяйте принцип наименьших привилегий для учётной записи БД: не давайте ей прав на чтение системных таблиц, если это не нужно.
  5. Установите WAF (Web Application Firewall), который может блокировать подозрительные запросы, содержащие EXTRACTVALUE или UPDATEXML.

Что делать, если вы нашли такую строку в логах?

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

  • не было ли успешных инъекций (ищите необычные записи в БД);
  • обновлены ли все компоненты CMS и библиотеки;
  • работает ли WAF и настроен ли он на блокировку таких запросов.

Помните: большинство автоматических сканеров просто перебирают известные шаблоны, и если ваше приложение использует параметризованные запросы, такие попытки не приведут к успеху.

Заключение

Строка " OR EXTRACTVALUE(7619,CONCAT(0x7e,((SELECT (ELT(7619=7619,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированный эксплойт для проверки и эксплуатации error-based SQL-инъекций в MySQL. Понимание принципов его работы помогает разработчикам и администраторам лучше защищать свои системы.

Источники