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

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

Если вкратце: злоумышленник подставляет эту строку в поле ввода веб-приложения, которое не фильтрует пользовательские данные. Сервер выполняет вредоносный SQL-код, и в ответе (или в логе ошибок) может «утечь» информация из базы.

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

Давайте разберём синтаксис по элементам, чтобы понять логику атаки.

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

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

Зачем это нужно?

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

Обычно с помощью EXTRACTVALUE или аналогичной UPDATEXML извлекают:

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

Важное ограничение: функция EXTRACTVALUE возвращает не более 32 символов. Поэтому для длинных значений применяют SUBSTR() или LIMIT, извлекая данные по частям.

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

Предположим, есть уязвимый параметр id в URL: https://example.com/product?id=1. Оригинальный запрос может выглядеть так:

SELECT * FROM products WHERE id = '1'

Атакующий подставляет:

1' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version()),0x7e))-- -

База вернёт ошибку: XPATH syntax error: '~8.0.32~'. Так узнаётся версия сервера. Далее можно извлекать таблицы и данные.

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

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

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

Заключение

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

Источники