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

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

В отличие от слепых инъекций (blind SQL injection), где информация добывается по косвенным признакам (например, по времени ответа), error-based метод заставляет базу данных выдать искомые данные прямо в тексте ошибки. Это делает атаку быстрой и удобной для автоматизированных инструментов вроде sqlmap.

Разбор по частям

1. Префикс %'))

Это попытка закрыть исходный SQL-запрос приложения. Символ % часто используется в LIKE-запросах, а ')) закрывает строковый литерал и скобки. Злоумышленник подбирает такое завершение, чтобы «вырваться» из контекста и добавить собственный код.

2. AND EXTRACTVALUE(1702, ...)

Функция EXTRACTVALUE() в MySQL предназначена для извлечения значения из XML-документа по XPath-выражению. Она принимает два аргумента: XML-строку и путь XPath. Если XPath-выражение синтаксически некорректно, MySQL выбрасывает ошибку XPATH syntax error, в тексте которой отображается переданный фрагмент.

Именно на этом строится эксплойт: злоумышленник передаёт в качестве XPath строку, содержащую результаты подзапроса, и сервер возвращает их в сообщении об ошибке.

3. CONCAT(0x7e, ((SELECT (ELT(1702=1702,1)))), 0x7e)

Функция CONCAT склеивает несколько строк. Здесь она соединяет:

  • 0x7e — шестнадцатеричное представление символа ~ (тильда). Используется как маркер начала и конца выводимых данных, чтобы их было легко найти в тексте ошибки.
  • Результат подзапроса SELECT (ELT(1702=1702,1)).
  • Снова 0x7e — закрывающая тильда.

Таким образом, в ошибке появится строка вида ~1~ (или другие данные, если подзапрос изменён).

4. ELT(1702=1702,1)

ELT() возвращает N-й элемент из списка строк. Первый аргумент — номер позиции, второй и последующие — сам список. Выражение 1702=1702 всегда истинно, то есть равно 1. Значит, ELT(1,1) вернёт строку '1'.

В реальной атаке вместо 1 подставляется подзапрос, извлекающий нужные данные, например: ELT(1, (SELECT version())). Но в данном примере показан «безопасный» тестовый вариант, который просто проверяет, что инъекция работает: если сервер вернёт ошибку с тильдами и единицей, значит, уязвимость подтверждена.

5. Комментарий -- -

Двойной дефис с пробелом — это комментарий в SQL. Он отсекает всё, что шло после инъекции в оригинальном запросе, чтобы не нарушать синтаксис. Пробел после -- обязателен в MySQL, иначе комментарий не распознается. Иногда вместо -- - используют # или /* */.

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

Предположим, уязвимый запрос выглядит так:

SELECT * FROM users WHERE name LIKE '%ЗНАЧЕНИЕ%'

Если подставить вместо ЗНАЧЕНИЕ нашу строку, получится:

SELECT * FROM users WHERE name LIKE '%%')) AND EXTRACTVALUE(1702,CONCAT(0x7e,((SELECT (ELT(1702=1702,1)))),0x7e))-- -%'

После закрытия кавычек и скобок добавляется условие AND EXTRACTVALUE(...). MySQL пытается вычислить EXTRACTVALUE с некорректным XPath (строка ~1~ не является валидным XPath), возникает ошибка:

XPATH syntax error: '~1~'

Эта ошибка возвращается клиенту (если вывод ошибок не отключён). Злоумышленник видит ~1~ и понимает, что инъекция успешна. Далее он может заменить 1 на подзапрос, например (SELECT database()), и получить имя текущей базы данных в тексте ошибки.

Зачем нужны тильды?

Символ ~ выбран не случайно. В выводе ошибки часто присутствует много служебного текста, и без маркеров сложно быстро найти полезную нагрузку. Тильды выступают в роли ограничителей, позволяя легко извлечь данные регулярным выражением. Кроме того, тильда редко встречается в обычных данных, что снижает риск ложных срабатываний.

Какие данные можно извлечь?

С помощью error-based инъекции через EXTRACTVALUE атакующий может получить:

  • версию MySQL (SELECT version());
  • имя текущей базы данных (SELECT database());
  • имя пользователя СУБД (SELECT user());
  • список таблиц и колонок из information_schema;
  • непосредственно данные из таблиц (логины, пароли, персональные сведения).

Ограничение — длина вывода в сообщении об ошибке. Обычно MySQL обрезает текст ошибки до 64 байт, поэтому данные извлекают посимвольно или по частям, используя функции SUBSTRING, MID и т.п.

Другие функции для error-based инъекций

Помимо EXTRACTVALUE, в MySQL существуют и другие функции, провоцирующие ошибки с выводом данных:

  • UPDATEXML() — аналогична EXTRACTVALUE, но работает с XML-документом и XPath.
  • GTID_SUBSET() — в некоторых версиях MySQL вызывает ошибку с указанием переданных значений.
  • EXP() — при переполнении выдаёт ошибку с числом.
  • JSON_KEYS() — в новых версиях может использоваться для error-based атак.

Инструмент sqlmap автоматически подбирает подходящую функцию в зависимости от версии СУБД и настроек сервера.

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

Основная причина успеха таких атак — отсутствие параметризации запросов. Вот ключевые меры защиты:

  1. Используйте подготовленные выражения (prepared statements). Это самый надёжный способ: данные передаются отдельно от SQL-кода и не могут изменить структуру запроса.
  2. Экранируйте специальные символы. Если параметризация невозможна, применяйте функции экранирования, например mysqli_real_escape_string().
  3. Ограничьте права пользователя БД. Не давайте приложению доступ к information_schema без необходимости и не используйте учётную запись root.
  4. Отключайте вывод ошибок на продакшене. Сообщения об ошибках должны писаться в лог, а не показываться пользователю.
  5. Используйте WAF. Веб-прикладной брандмауэр может блокировать типовые сигнатуры SQL-инъекций, включая EXTRACTVALUE.
  6. Регулярно обновляйте СУБД и фреймворки. В новых версиях некоторые функции могут быть удалены или изменены, что усложняет эксплуатацию.

Заключение

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

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

Источники