Что это за строка?
Строка '))) AND EXTRACTVALUE(7849,CONCAT(0x7e,((SELECT (ELT(7849=7849,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции (SQL-инъекция, основанная на ошибках). Она предназначена для внедрения в уязвимый SQL-запрос с целью заставить базу данных выдать конфиденциальную информацию через сообщение об ошибке.
Такие полезные нагрузки часто встречаются в отчётах сканеров уязвимостей, в логах веб-серверов и в базах эксплойтов. Понимание их устройства помогает разработчикам и специалистам по безопасности лучше защищать приложения.
Разбор по частям
Рассмотрим каждый элемент конструкции.
Начало: ')))
Символы '))) — это попытка закрыть ранее открытые кавычки и скобки в исходном SQL-запросе. Злоумышленник предполагает, что уязвимый параметр вставляется внутрь выражения, например: SELECT * FROM users WHERE id = ('$input'). Чтобы синтаксис стал корректным, нужно закрыть строку и скобки. Количество скобок подбирается экспериментально.
Оператор AND
Логический оператор AND добавляет новое условие к существующему запросу. Если исходный запрос возвращал какие-то строки, то после добавления AND ... результат может измениться, но главное — выполнится внедрённая функция.
Функция EXTRACTVALUE()
EXTRACTVALUE(XML_fragment, XPath_expression) — это встроенная функция MySQL (до версии 8.0.17 включительно), предназначенная для извлечения данных из XML-документа с помощью XPath. Она принимает два строковых аргумента: фрагмент XML-разметки и выражение XPath. Функция возвращает текст (CDATA) первого текстового узла, который является дочерним по отношению к элементу или элементам, соответствующим XPath-выражению.
Ключевая особенность: если XPath-выражение синтаксически некорректно, MySQL генерирует ошибку, в тексте которой содержится переданное выражение. Это и используется для извлечения данных.
Аргументы 7849 и CONCAT(0x7e, ..., 0x7e)
Первый аргумент — произвольное число или строка, которая не является корректным XML. Второй аргумент — результат функции CONCAT, склеивающей символ ~ (код 0x7e), некоторое выражение и снова ~. Символ ~ используется как маркер, чтобы в сообщении об ошибке легко было найти внедрённые данные.
Подзапрос (SELECT (ELT(7849=7849,1)))
Внутри CONCAT находится подзапрос, возвращающий результат функции ELT(N, str1, str2, ...). ELT возвращает N-ю строку из списка. В данном случае условие 7849=7849 всегда истинно, поэтому возвращается 1 (первая строка). Это простейшая проверка работоспособности инъекции: если ошибка появится, значит, внедрение сработало.
Комментарий -- -
Два дефиса и пробел (или дефис) — это комментарий в SQL, который отсекает оставшуюся часть исходного запроса, чтобы не нарушать синтаксис.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM articles WHERE id = '$id';Если передать в параметр id строку '))) AND EXTRACTVALUE(7849,CONCAT(0x7e,((SELECT (ELT(7849=7849,1)))),0x7e))-- -, то после подстановки получится:
SELECT * FROM articles WHERE id = ''))) AND EXTRACTVALUE(7849,CONCAT(0x7e,((SELECT (ELT(7849=7849,1)))),0x7e))-- -';СУБД попытается выполнить EXTRACTVALUE с первым аргументом 7849 (не XML) и вторым аргументом, содержащим символ ~. Поскольку 7849 не является корректным XML-документом, MySQL выдаст ошибку вида:
XPATH syntax error: '~1~'
В сообщении об ошибке появится ~1~ — результат выполнения подзапроса. В реальной атаке вместо ELT(7849=7849,1) подставляются вызовы, извлекающие имена таблиц, колонок, версию СУБД, логины и пароли пользователей. Например, (SELECT version()) или (SELECT table_name FROM information_schema.tables LIMIT 0,1).
Зачем это нужно злоумышленнику
Error-based SQL-инъекции позволяют получать данные напрямую из сообщений об ошибках, когда приложение выводит их пользователю. Это один из самых быстрых способов эксплуатации, так как не требует слепого перебора (boolean-based) или временных задержек (time-based).
Основные цели:
- Получение версии MySQL и операционной системы.
- Извлечение имён баз данных, таблиц и колонок через
information_schema. - Чтение учётных данных пользователей.
- В некоторых случаях — выполнение произвольных запросов и даже команд ОС (при наличии прав).
Меры защиты
Чтобы предотвратить подобные атаки, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией — это самый надёжный способ.
- Экранировать специальные символы при невозможности использовать параметризацию.
- Отключить вывод ошибок СУБД в production-окружении, чтобы сообщения не попадали к пользователю.
- Ограничить права пользователя БД, от имени которого работает приложение: запретить доступ к
information_schema,mysqlи другим системным таблицам. - Регулярно обновлять MySQL: в версии 8.0.17 функция
EXTRACTVALUEбыла удалена, что усложняет эксплуатацию, но не отменяет необходимость других мер. - Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Заключение
Строка '))) AND EXTRACTVALUE(7849,CONCAT(0x7e,((SELECT (ELT(7849=7849,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции, демонстрирующий, как через функцию EXTRACTVALUE и намеренно вызванную ошибку XPath можно извлечь данные из базы. Понимание таких конструкций помогает специалистам по безопасности выявлять уязвимости и правильно настраивать защиту веб-приложений.
Комментарии
—Войдите, чтобы оставить комментарий