Что это за строка?
Запрос пользователя: "))) AND EXTRACTVALUE(9232,CONCAT(0x7e,((SELECT (ELT(9232=9232,1)))),0x7e))-- - — это фрагмент полезной нагрузки (payload) для SQL-инъекции, а именно для атаки типа error-based (инъекция, основанная на ошибках). Такая строка встречается в логах веб-серверов, в полях ввода форм или в параметрах URL, когда злоумышленник пытается проверить уязвимость приложения или извлечь данные из базы данных MySQL.
Подобные конструкции часто обсуждаются на форумах по информационной безопасности. Например, в одном из сообщений приводится похожий пример: %" AND EXTRACTVALUE (8635,CONCAT (0x7e, ( (SELECT (ELT (8635=8635,1)))),0x7e))-- -, который описывается как «классический пример error-based SQL-инъекции для СУБД MySQL». Другой пример: ) AND EXTRACTVALUE (6832,CONCAT (0x7e, ( (SELECT (ELT (6832=6832,1)))),0x7e))-- - — также относится к этой категории.
В данной статье мы разберём, как именно работает эта инъекция, какие функции задействованы и как от неё защититься.
Разбор payload по частям
Рассмотрим строку по частям:
")))— последовательность кавычек и скобок. Она нужна, чтобы «закрыть» предыдущие конструкции в исходном SQL-запросе и выйти за его пределы. Точный набор символов зависит от контекста: иногда это одна кавычка, иногда комбинация с закрывающими скобками.AND— логический оператор, добавляющий условие к запросу. В error-based инъекции часто используется для внедрения функции, которая вызовет ошибку.EXTRACTVALUE(9232, CONCAT(...))— ключевая функция MySQL.EXTRACTVALUE(XML_document, XPath_expression)извлекает значение из XML-документа по XPath-выражению. Если XPath-выражение некорректно, MySQL выдаёт ошибку, в текст которой попадает часть переданного выражения. Это и позволяет злоумышленнику «прочитать» результат подзапроса.9232— произвольное число (или строка), которое передаётся в качестве первого аргумента. Оно может быть любым; часто используют случайное число, чтобы избежать кэширования.CONCAT(0x7e, ((SELECT (ELT(9232=9232,1)))), 0x7e)— конкатенация.0x7e— это шестнадцатеричный код символа~(тильда). Тильда используется как разделитель, чтобы облегчить извлечение данных из сообщения об ошибке. Внутри — подзапросSELECT (ELT(9232=9232,1)).ELT(N, str1, str2, ...)— функция MySQL, возвращающая N-ю строку из списка. Если N=1, возвращается первая строка. В данном случаеELT(9232=9232,1)— условие9232=9232всегда истинно (1), поэтому возвращается1. Это простейшая проверка работоспособности инъекции: если ошибка появится, значит, функция выполнилась.-- -— комментарий в MySQL (пробел после двух дефисов обязателен). Он «отрезает» оставшуюся часть исходного запроса, чтобы синтаксис стал корректным.
В реальной атаке вместо ELT(9232=9232,1) подставляется подзапрос, возвращающий нужные данные, например: (SELECT password FROM users LIMIT 1). Тогда CONCAT объединяет тильду, результат подзапроса и ещё одну тильду, а EXTRACTVALUE пытается разобрать эту строку как XPath и выдаёт ошибку вида: XPATH syntax error: '~admin123~'. Так злоумышленник получает значение из базы.
Почему это работает?
Функция EXTRACTVALUE (как и UPDATEXML) при некорректном XPath-выражении генерирует ошибку, в текст которой включается переданная строка. Это особенность поведения MySQL (и MariaDB). Если приложение выводит сообщения об ошибках базы данных на страницу (что часто случается в режиме отладки), злоумышленник может прочитать эти сообщения и получить данные.
Таким образом, error-based инъекция — это метод слепого извлечения данных, при котором вместо прямого вывода результата используется канал ошибок.
Примеры похожих payload
В результатах поиска упоминается также ' UNION ALL SELECT NULL,concat(0x28,username,0x3a,password,0x29) FROM users # — это пример UNION-based инъекции. Ошибка «The used SELECT statements have a different number of columns» возникает, когда количество столбцов в UNION SELECT не совпадает с исходным запросом. Это ещё один распространённый тип атак.
Наш же запрос с EXTRACTVALUE относится именно к error-based, и его главная цель — заставить базу вернуть данные в сообщении об ошибке.
Как защититься от SQL-инъекций?
Основные меры защиты:
- Параметризованные запросы (prepared statements). Это самый надёжный способ: данные передаются отдельно от SQL-кода и не могут изменить структуру запроса.
- Экранирование специальных символов. Если по каким-то причинам нельзя использовать параметризацию, применяйте функции экранирования, например
mysqli_real_escape_stringв PHP. Но это менее надёжно. - Отключение вывода ошибок БД в production. Сообщения об ошибках должны писаться в лог, а пользователю показываться общая страница ошибки. Это затрудняет эксплуатацию error-based инъекций.
- Принцип наименьших привилегий. Учётная запись, от имени которой работает приложение, должна иметь только необходимые права. Например, не иметь доступа к системным таблицам.
- Регулярное обновление СУБД и фреймворков. Хотя
EXTRACTVALUEне является уязвимостью сама по себе, в новых версиях MySQL (начиная с 8.0.17) функция помечена как устаревшая, и её использование может быть ограничено. - Использование WAF (Web Application Firewall). Современные WAF умеют распознавать подобные payload и блокировать запросы.
Важно понимать, что сам по себе запрос с EXTRACTVALUE не является вирусом или вредоносным кодом — это лишь инструмент, который может быть использован злоумышленником при наличии уязвимости. Если вы встретили такую строку в логах, это повод проверить своё приложение на SQL-инъекции.
Заключение
Строка "))) AND EXTRACTVALUE(9232,CONCAT(0x7e,((SELECT (ELT(9232=9232,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для MySQL. Она использует функцию EXTRACTVALUE для вызова ошибки, содержащей результат подзапроса, и функции CONCAT, ELT для формирования полезной нагрузки. Понимание механизма таких атак помогает разработчикам и администраторам правильно выстраивать защиту.
Если вы нашли подобную строку в своём проекте, немедленно проверьте все места, где пользовательский ввод попадает в SQL-запросы, и убедитесь, что используются параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий