Что это за строка?
Строка %' AND EXTRACTVALUE(2015,CONCAT(0x7e,((SELECT (ELT(2015=2015,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для внедрения в уязвимый SQL-запрос с целью заставить базу данных вывести содержимое через сообщение об ошибке. Подобные конструкции часто встречаются в отчётах сканеров уязвимостей и в эксплойтах, нацеленных на веб-приложения, которые не фильтруют пользовательский ввод.
В основе лежит игра на синтаксисе XPath и функциях MySQL. Давайте разберём каждый элемент.
Разбор составных частей
1. Начало: %'
Символ % часто используется в SQL-запросах как шаблон для оператора LIKE. Закрывающая кавычка ' завершает строковый литерал, в который внедряется инъекция. Вместе %' пытается «закрыть» предполагаемое условие поиска, чтобы затем добавить собственный код.
2. AND EXTRACTVALUE(2015,CONCAT(0x7e,((SELECT (ELT(2015=2015,1)))),0x7e))
Это ядро инъекции. Функция EXTRACTVALUE(XML, XPath) извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение синтаксически некорректно, MySQL генерирует ошибку, в тексте которой отображается переданный аргумент. Этим и пользуются злоумышленники.
- Первый аргумент
2015— произвольное число, которое не является корректным XML. Оно нужно лишь для того, чтобы функция была вызвана. - Второй аргумент формируется через
CONCAT(0x7e, ((SELECT (ELT(2015=2015,1)))), 0x7e). Здесь0x7e— это шестнадцатеричное представление символа~(тильда). Тильда недопустима в начале XPath-выражения, поэтому она гарантированно вызывает синтаксическую ошибку. - Внутренний подзапрос
(SELECT (ELT(2015=2015,1)))возвращает результат функцииELT(N, str1, str2, ...).ELTвыбирает N-ю строку из списка. В данном случае условие2015=2015всегда истинно (возвращает 1), поэтомуELT(1, 1)вернёт строку'1'. Это простейшая проверка, которая подтверждает, что инъекция работает: если в ответе появится ошибка с числом 1, значит, уязвимость есть.
Фактически, конструкция заставляет MySQL выдать сообщение об ошибке вида: XPATH syntax error: '~1~'. Вместо 1 может быть любой другой результат подзапроса, что позволяет извлекать произвольные данные (имена таблиц, логины, пароли) посимвольно.
3. Комментарий: -- -
Два дефиса с пробелом (или без) в MySQL означают начало комментария до конца строки. Это необходимо, чтобы «отрезать» оставшуюся часть оригинального SQL-запроса, которая могла бы помешать выполнению инъекции. Пробел после -- обязателен в некоторых реализациях, но часто пишут -- - для надёжности.
Как это работает на практике
Предположим, веб-приложение выполняет запрос:
SELECT * FROM users WHERE name LIKE '%$input%';
Если пользователь передаст в $input нашу строку, запрос превратится в:
SELECT * FROM users WHERE name LIKE '%%' AND EXTRACTVALUE(2015,CONCAT(0x7e,((SELECT (ELT(2015=2015,1)))),0x7e))-- -%';
После подстановки MySQL выполнит EXTRACTVALUE, что приведёт к ошибке с текстом, содержащим результат подзапроса. Злоумышленник увидит в ответе сервера что-то вроде:
XPATH syntax error: '~1~'
Это сигнал, что инъекция успешна. Далее вместо ELT(2015=2015,1) можно подставить, например, SELECT version() или SELECT table_name FROM information_schema.tables LIMIT 1, чтобы получить конфиденциальные данные.
Зачем используется ELT и CONCAT?
Функция ELT здесь — простейший способ вернуть константу или результат другого выражения. В более сложных эксплойтах её заменяют на подзапросы, возвращающие нужную информацию. CONCAT склеивает тильды с полезной нагрузкой, чтобы гарантировать невалидный XPath и одновременно обрамить выводимые данные маркерами ~. Это облегчает автоматический парсинг ответа сервера инструментами вроде sqlmap.
Опасность и защита
Error-based SQL-инъекции чрезвычайно опасны, так как позволяют злоумышленнику получить полный доступ к базе данных, включая учётные записи пользователей, платёжную информацию и коммерческие тайны. Основная причина — недостаточная фильтрация входных данных и использование конкатенации строк вместо подготовленных выражений (prepared statements).
Чтобы защититься, разработчикам следует:
- Использовать параметризованные запросы (prepared statements) во всех СУБД.
- Применять ORM или библиотеки, которые автоматически экранируют спецсимволы.
- Отключить вывод подробных ошибок MySQL в продакшене (параметр
display_errors). - Регулярно проводить сканирование уязвимостей и аудит кода.
Также рекомендуется ограничить права пользователя базы данных, от имени которого работает приложение: запретить доступ к information_schema и другим системным таблицам, если он не нужен.
Вывод
Строка %' AND EXTRACTVALUE(2015,CONCAT(0x7e,((SELECT (ELT(2015=2015,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированный эксплойт для проверки наличия error-based SQL-инъекции в MySQL. Понимание её работы помогает специалистам по безопасности выявлять и устранять подобные уязвимости, а разработчикам — писать защищённый код.
Комментарии
—Войдите, чтобы оставить комментарий