Что такое SQL-инъекция и при чём здесь EXTRACTVALUE
SQL-инъекция — один из самых распространённых способов атаки на веб-приложения. Злоумышленник внедряет в запрос к базе данных вредоносный код, чтобы получить доступ к данным, изменить их или даже выполнить команды на сервере. В данном запросе используется функция EXTRACTVALUE — встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Однако атакующие научились применять её для извлечения данных из самой базы, вызывая ошибки, которые содержат результаты подзапросов.
Рассматриваемый запрос: %' AND EXTRACTVALUE(1410,CONCAT(0x7e,((SELECT (ELT(1410=1410,1)))),0x7e))-- - — это типичный пример слепой SQL-инъекции, основанной на ошибках (error-based). Давайте разберём его по частям.
Анатомия полезной нагрузки
Начнём с начала. Символ %' — это попытка закрыть строковый литерал в исходном SQL-запросе. Знак процента часто используется в LIKE-запросах, и атакующий предполагает, что его ввод подставляется в условие с LIKE. Далее идёт AND — логическое И, которое позволяет добавить условие. Затем вызывается EXTRACTVALUE(1410, CONCAT(...)). Первый аргумент — 1410 — это просто число, которое будет интерпретировано как XML-фрагмент (на самом деле это не XML, но функция попытается его разобрать). Второй аргумент — XPath-выражение, которое формируется динамически через CONCAT.
Внутри CONCAT мы видим 0x7e — это шестнадцатеричное представление символа тильды (~). Тильда добавляется, чтобы отделить результат подзапроса от остального текста в сообщении об ошибке. Далее идёт подзапрос (SELECT (ELT(1410=1410,1))). Функция ELT возвращает N-й элемент из списка. В данном случае 1410=1410 — это всегда истинное условие (1), поэтому ELT(1,1) вернёт строку '1'. Таким образом, подзапрос возвращает строку '1'.
Итак, CONCAT собирает строку вида ~1~. Затем EXTRACTVALUE пытается выполнить XPath-запрос ~1~ к числу 1410 (которое не является корректным XML). Естественно, это вызывает ошибку, и MySQL выдаёт сообщение, содержащее переданный XPath-выражение, то есть ~1~. В результате атакующий видит в ответе сервера строку с тильдами и понимает, что инъекция сработала. В реальной атаке вместо '1' мог бы быть, например, пароль пользователя или имя базы данных.
Зачем нужен ELT и как это работает
Функция ELT(N, str1, str2, ...) возвращает строку под номером N. Если N=1, возвращается первая строка. В нашем случае 1410=1410 — это выражение, которое в MySQL возвращает 1 (истина). Таким образом, ELT(1,1) возвращает '1'. Это простой способ сгенерировать предсказуемое значение для тестирования уязвимости. В более сложных атаках вместо '1' подставляется результат другого подзапроса, например, (SELECT password FROM users LIMIT 1). Тогда в сообщении об ошибке появится хеш пароля.
Комментарий -- - в конце обрезает оставшуюся часть исходного запроса, чтобы синтаксис оставался корректным. Пробел после двух дефисов обязателен в MySQL, а дополнительный дефис часто добавляют для надёжности.
Почему это опасно и как защититься
Подобные инъекции позволяют злоумышленнику извлекать произвольные данные из базы, включая учётные записи, персональные данные и коммерческую тайну. Основная причина уязвимости — недостаточная фильтрация пользовательского ввода и конкатенация его в SQL-запрос без экранирования. Для защиты необходимо использовать параметризованные запросы (prepared statements), которые отделяют код от данных. Также рекомендуется отключить вывод подробных ошибок базы данных в production-окружении, чтобы злоумышленник не мог получить информацию через сообщения об ошибках. Регулярное обновление СУБД и использование веб-фаерволов (WAF) также снижают риск.
Важно: функция EXTRACTVALUE устарела начиная с MySQL 5.7.6 и удалена в MySQL 8.0. Однако во многих устаревших системах она всё ещё доступна, поэтому атаки с её использованием остаются актуальными.
В заключение, разобранный запрос — это классический пример error-based SQL-инъекции, использующей особенности обработки XML в MySQL. Понимание таких техник помогает разработчикам и специалистам по безопасности лучше защищать свои приложения.
Комментарии
—Войдите, чтобы оставить комментарий