Что такое ' ) AND EXTRACTVALUE(4347,CONCAT(0x7e,((SELECT (ELT(4347=4347,1)))),0x7e))-- -
Эта строка представляет собой классический пример error-based SQL-инъекции (SQL-инъекция, основанная на ошибках) для СУБД MySQL. Она предназначена для внедрения в уязвимый SQL-запрос с целью заставить базу данных вернуть данные через сообщение об ошибке. Подобные конструкции широко используются злоумышленниками для извлечения информации из базы, когда прямой вывод данных невозможен.
Разберём её по частям, чтобы понять, как она работает и какую угрозу представляет.
Структура инъекции
Строка состоит из нескольких частей:
')— закрывает ранее открытую скобку и кавычку в уязвимом запросе, чтобы внедрить свой код.AND— логический оператор, присоединяющий наше условие к исходному запросу.EXTRACTVALUE(4347,CONCAT(0x7e,((SELECT (ELT(4347=4347,1)))),0x7e))— вызов функцииEXTRACTVALUE, которая вызывает ошибку, содержащую результат подзапроса.-- -— комментарий, обрезающий остаток исходного SQL-запроса.
Как работает EXTRACTVALUE
Функция EXTRACTVALUE() в MySQL принимает два строковых аргумента: фрагмент XML-разметки и выражение XPath. Она возвращает текст (CDATA) первого текстового узла, который является дочерним для элемента или элементов, соответствующих XPath-выражению. Если XPath-выражение некорректно, функция генерирует ошибку.
В нашем случае первый аргумент — 4347 (просто число, не являющееся валидным XML), а второй — CONCAT(0x7e,((SELECT (ELT(4347=4347,1)))),0x7e). Это выражение формирует строку, начиная и заканчивая символом ~ (0x7e в шестнадцатеричном виде). Внутри — подзапрос SELECT (ELT(4347=4347,1)).
Функция ELT и условие 4347=4347
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(4347=4347,1) — это упрощённый пример: условие 4347=4347 всегда истинно (возвращает 1), поэтому ELT вернёт первый элемент — 1. В реальной атаке вместо 1 может быть подставлено имя таблицы, столбца или другие данные, которые злоумышленник хочет извлечь.
Таким образом, CONCAT создаёт строку вида ~1~. Затем EXTRACTVALUE пытается интерпретировать число 4347 как XML и применить XPath-выражение ~1~. Поскольку это невалидный XPath, MySQL выдаёт ошибку, в тексте которой будет содержаться переданная строка, то есть ~1~. Именно через эту ошибку атакующий получает данные.
Зачем нужен комментарий -- -
Комментарий -- - (два дефиса, пробел и дефис) отсекает оставшуюся часть оригинального SQL-запроса, чтобы синтаксис был корректным. В MySQL комментарий начинается с -- (два дефиса и пробел) и продолжается до конца строки. Добавление дефиса после пробела — распространённый приём для обхода некоторых фильтров.
Как эксплуатируется уязвимость
Предположим, есть уязвимый параметр id в URL: example.com/product.php?id=1. Исходный запрос может выглядеть так:
SELECT * FROM products WHERE id = ('1')
Если подставить вместо 1 нашу строку, запрос станет:
SELECT * FROM products WHERE id = ('1') AND EXTRACTVALUE(4347,CONCAT(0x7e,((SELECT (ELT(4347=4347,1)))),0x7e))-- -')
После закрытия кавычки и скобки внедряется условие AND EXTRACTVALUE(...), которое вызывает ошибку. В результате на странице отобразится сообщение об ошибке MySQL, содержащее результат подзапроса. В нашем примере это будет ~1~, но в реальной атаке злоумышленник может заменить 1 на database(), version() или подзапрос, извлекающий пароли пользователей.
Какие данные можно извлечь
С помощью error-based SQL-инъекции через EXTRACTVALUE атакующий может получить:
- Имя текущей базы данных (
database()). - Версию MySQL (
version()). - Имена таблиц и столбцов из
information_schema. - Логины и пароли пользователей (хеши).
- Любые другие данные, доступные в базе.
Ограничение — длина выводимой строки. Обычно MySQL обрезает сообщение об ошибке до 64 символов, поэтому злоумышленники используют функции SUBSTRING или LIMIT для посимвольного извлечения.
Модификации запроса
Вместо EXTRACTVALUE могут использоваться другие функции, вызывающие ошибки: UPDATEXML, GTID_SUBSET, EXP (в комбинации с ~). Также часто применяют CONCAT с 0x7e для обрамления выводимых данных, чтобы их было легко найти в тексте ошибки. Число 4347 — произвольное, оно может быть любым, важно лишь, чтобы оно не было валидным XML.
Как защититься
Основной способ защиты от SQL-инъекций — использование параметризованных запросов (prepared statements). Это гарантирует, что пользовательский ввод никогда не будет интерпретирован как SQL-код. Дополнительные меры:
- Экранирование специальных символов с помощью
mysqli_real_escape_stringили аналогичных функций. - Валидация и фильтрация входных данных (например, приведение к целому числу).
- Использование ORM, которые автоматически параметризуют запросы.
- Ограничение прав пользователя базы данных (не давать прав на чтение
information_schemaи файловой системы). - Отключение вывода ошибок MySQL на продакшене, чтобы сообщения об ошибках не попадали к пользователю.
Важно понимать, что error-based инъекции — лишь один из многих методов атак. Регулярное тестирование на проникновение и сканеры уязвимостей помогают выявить такие дыры.
Заключение
Строка ') AND EXTRACTVALUE(4347,CONCAT(0x7e,((SELECT (ELT(4347=4347,1)))),0x7e))-- - — это типичный эксплойт для error-based SQL-инъекции в MySQL. Он использует функцию EXTRACTVALUE для генерации ошибки, содержащей данные из подзапроса. Понимание подобных конструкций необходимо как специалистам по безопасности, так и разработчикам, чтобы своевременно закрывать уязвимости и защищать свои приложения.
Комментарии
—Войдите, чтобы оставить комментарий