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

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

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

Анатомия инъекции

1. Начало: %"

Символ % — это подстановочный знак в SQL-запросах (например, в LIKE). Кавычка " закрывает строковый литерал в оригинальном запросе, после чего злоумышленник добавляет AND .... Таким образом, исходный запрос, скорее всего, выглядел как SELECT ... WHERE name LIKE '%" — и инъекция ломает его структуру.

2. Функция EXTRACTVALUE(8635, CONCAT(...))

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

Однако при передаче некорректного XPath-выражения MySQL генерирует ошибку, в тексте которой отображается переданное выражение. Это и есть основа error-based инъекции: злоумышленник может поместить в XPath результат подзапроса, и он окажется в сообщении об ошибке.

3. CONCAT(0x7e, ((SELECT ...)), 0x7e)

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

Внутри CONCAT находится подзапрос (SELECT (ELT(8635=8635,1))).

4. ELT(8635=8635, 1)

ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 8635=8635 — это логическое выражение, которое всегда истинно (1). Таким образом, ELT(1, 1) вернёт строку '1'. В реальной атаке вместо этого подзапроса был бы запрос к базе, например, SELECT version() или SELECT password FROM users LIMIT 1. Но в данном примере используется безобидная константа, чтобы продемонстрировать работу механизма.

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

Двойной дефис с пробелом (или -- -) — это комментарий в SQL. Он отсекает оставшуюся часть оригинального запроса, чтобы синтаксис был корректным.

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

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

SELECT * FROM articles WHERE title LIKE '%" AND EXTRACTVALUE(8635,CONCAT(0x7e,((SELECT (ELT(8635=8635,1)))),0x7e))-- -%'

После подстановки получается:

SELECT * FROM articles WHERE title LIKE '%" AND EXTRACTVALUE(8635,CONCAT(0x7e,((SELECT (ELT(8635=8635,1)))),0x7e))-- -%'

MySQL выполняет функцию EXTRACTVALUE, которая пытается разобрать XPath-выражение ~1~. Поскольку это невалидный XPath, возникает ошибка вида:

XPATH syntax error: '~1~'

В сообщении об ошибке мы видим ~1~ — это и есть результат подзапроса. Если бы вместо 1 стоял, например, (SELECT database()), мы бы увидели имя текущей базы данных.

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

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

  • версию MySQL;
  • имя текущего пользователя базы;
  • названия таблиц и столбцов;
  • логины и пароли пользователей;
  • любые другие данные, доступные в рамках прав соединения.

Меры защиты

Чтобы предотвратить подобные атаки, необходимо:

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

Вывод

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

Источники