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

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

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

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

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

Именно эта особенность используется в error-based инъекциях: злоумышленник конструирует XPath-выражение так, чтобы в тексте ошибки появились данные из базы. Например, если передать в качестве XPath строку с недопустимыми символами, MySQL вернёт ошибку вида XPATH syntax error: '...', где ... — это переданная строка. Если в эту строку подставить результат подзапроса, то в ошибке отобразятся данные.

Например, запрос SELECT EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)); вызовет ошибку: XPATH syntax error: '~5.7.34~'. Так злоумышленник узнаёт версию СУБД.

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

Рассмотрим по частям:

  • )) — закрывающие скобки, которые завершают предыдущий запрос. Злоумышленник предполагает, что исходный запрос имеет вложенные скобки, и пытается «выровнять» синтаксис.
  • OR — логический оператор. Если предыдущее условие ложно, выполняется следующее. Это позволяет внедрить дополнительное выражение.
  • EXTRACTVALUE(5029,CONCAT(0x7e,((SELECT (ELT(5029=5029,1)))),0x7e)) — вызов функции EXTRACTVALUE с двумя аргументами. Первый аргумент — число 5029 (может быть любым, часто используется как идентификатор). Второй аргумент — CONCAT(0x7e, ((SELECT (ELT(5029=5029,1)))), 0x7e).
  • 0x7e — шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы в ошибке было легко выделить полезную нагрузку.
  • ELT(5029=5029,1) — функция ELT возвращает N-й элемент из списка. Здесь 5029=5029 — это всегда истина (1), поэтому ELT(1,1) вернёт 1. Это простейшая проверка, которая не несёт полезной нагрузки, но показывает шаблон. В реальной атаке вместо 1 подставляется подзапрос, например (SELECT user()).
  • -- - — комментарий в MySQL. Всё, что идёт после -- (пробел обязателен), игнорируется. Это позволяет отбросить остаток оригинального запроса, который мог бы вызвать синтаксическую ошибку.

Таким образом, строка пытается заставить сервер выполнить EXTRACTVALUE с заведомо некорректным XPath-выражением, содержащим результат подзапроса. В данном примере подзапрос возвращает просто 1, но в реальной атаке там могут быть имена таблиц, столбцов, пароли и т.д.

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

Цель error-based SQL-инъекции — получить данные из базы, когда другие методы (например, UNION) недоступны. Если сайт отображает ошибки MySQL, злоумышленник может пошагово извлекать информацию: версию СУБД, имя текущей базы, список таблиц, столбцов и, наконец, сами данные (логины, пароли, номера карт).

Конструкция с EXTRACTVALUE — один из многих приёмов. Аналогично работают UPDATEXML, GTID_SUBSET, EXP и другие функции, вызывающие ошибки с контролируемым текстом.

Пример реальной атаки

Предположим, на сайте есть скрипт product.php?id=1, который выполняет запрос:

SELECT * FROM products WHERE id = $id;

Злоумышленник передаёт id=1)) OR EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database()),0x7e))-- -. Если приложение не фильтрует ввод, итоговый запрос станет:

SELECT * FROM products WHERE id = 1)) OR EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database()),0x7e))-- -;

Сервер выполнит подзапрос, получит имя базы и попытается вставить его в XPath. Возникнет ошибка, которая отобразится на странице. Так злоумышленник узнает имя базы. Затем аналогично извлекаются таблицы и данные.

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

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

  • Отключить вывод ошибок MySQL на продакшене (display_errors = off).
  • Использовать ORM или библиотеки, которые автоматически экранируют данные.
  • Применять принцип наименьших привилегий для пользователя БД: не давать ему прав на чтение системных таблиц, если это не нужно.
  • Регулярно обновлять СУБД и веб-приложения.
  • Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.

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

Вывод

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

Источники