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

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

Подобные строки часто встречаются в отчётах пентестеров, в материалах по безопасности и в учебных заданиях (например, на платформах DVWA или SQLZoo). Они демонстрируют, как злоумышленник может извлечь информацию из базы данных, если веб-приложение не фильтрует пользовательский ввод.

Разбор компонентов инъекции

Давайте посмотрим, из чего состоит эта строка и как она работает.

1. %')) — закрытие исходного запроса

Символы %' и )) предназначены для того, чтобы «закрыть» предыдущие части SQL-запроса, которые формируются в уязвимом приложении. Например, если исходный запрос выглядит так:

SELECT * FROM users WHERE name = '%' AND password = '...'

то вставка %')) может привести к преждевременному закрытию строкового литерала и скобок, после чего добавляется новый оператор AND с полезной нагрузкой.

2. AND EXTRACTVALUE(4419, CONCAT(0x7e, ...)) — вызов функции с ошибкой

Функция EXTRACTVALUE(XML_document, XPath_expression) в MySQL предназначена для извлечения значения из XML-документа по XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой может содержаться переданное значение. Это и есть основа error-based инъекции.

В нашем случае первым аргументом передаётся число 4419 (произвольный идентификатор), а вторым — результат CONCAT(0x7e, ((SELECT (ELT(4419=4419,1)))), 0x7e). Символ 0x7e — это тильда (~), которая используется как разделитель, чтобы облегчить поиск вывода в сообщении об ошибке.

3. ELT(4419=4419, 1) — генерация полезной нагрузки

Функция ELT(N, str1, str2, ...) возвращает строку с номером N из списка. В данном случае 4419=4419 — это логическое выражение, которое всегда истинно (1). Таким образом, ELT(1, 1) возвращает '1'. Это простейшая демонстрация: в реальной атаке вместо 1 мог бы быть подзапрос, извлекающий имя пользователя или хеш пароля.

Например, вместо ELT(4419=4419,1) злоумышленник мог бы использовать ELT(4419=4419, (SELECT password FROM users LIMIT 1)), и тогда в ошибке отобразился бы пароль.

4. -- - — комментарий

Последовательность -- (с пробелом после) в MySQL означает начало комментария, который продолжается до конца строки. Это позволяет «отбросить» оставшуюся часть оригинального запроса, чтобы синтаксис стал корректным.

Как работает атака целиком

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

$query = "SELECT * FROM items WHERE category = '" . $_GET['cat'] . "'";

Если передать строку %')) AND EXTRACTVALUE(4419,CONCAT(0x7e,((SELECT (ELT(4419=4419,1)))),0x7e))-- -, то итоговый запрос примет вид:

SELECT * FROM items WHERE category = '%')) AND EXTRACTVALUE(4419,CONCAT(0x7e,((SELECT (ELT(4419=4419,1)))),0x7e))-- -'

После закрытия кавычки и скобок (хотя в данном примере скобки могут быть лишними, они часто используются для обхода фильтров) добавляется условие AND EXTRACTVALUE(...). При выполнении MySQL попытается вычислить EXTRACTVALUE и сгенерирует ошибку, так как второй аргумент не является корректным XPath. В тексте ошибки появится что-то вроде:

XPATH syntax error: '~1~'

Таким образом, атакующий видит результат выполнения вложенного запроса (в нашем случае — просто число 1).

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

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

Однако для успешной эксплуатации необходимо, чтобы сервер возвращал подробные ошибки. В production-окружениях часто отключают вывод ошибок, что снижает риск.

Как защититься от таких инъекций?

  • Используйте параметризованные запросы (prepared statements). Это самый надёжный способ: данные передаются отдельно от SQL-кода, и внедрение становится невозможным.
  • Экранируйте специальные символы. Если по каким-то причинам нельзя использовать подготовленные выражения, применяйте функции экранирования (например, mysqli_real_escape_string в PHP).
  • Отключите вывод ошибок БД в production. Сообщения об ошибках должны логироваться, но не отображаться пользователю.
  • Ограничьте права пользователя БД. Не давайте приложению прав на чтение системных таблиц или выполнение опасных функций.
  • Регулярно проводите аудит безопасности. Используйте сканеры уязвимостей и пентесты.

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

Функция EXTRACTVALUE сама по себе не является вредоносной. Она применяется для работы с XML-данными в MySQL. Например:

SELECT EXTRACTVALUE('<root><user>admin</user></root>', '/root/user');

Вернёт admin. Опасность возникает только тогда, когда пользовательский ввод попадает в SQL-запрос без должной обработки.

Заключение

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

Источники