Что это за строка?
Строка %") AND EXTRACTVALUE(8877,CONCAT(0x7e,((SELECT (ELT(8877=8877,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто встречаются в отчётах пентестеров и в базах уязвимостей, например, на Exploit Database.
В данной статье мы разберём каждый элемент этой строки, объясним, как она работает, и покажем, какие механизмы защиты могут ей противостоять.
Разбор компонентов инъекции
Ключевая последовательность %")
Начинается строка с %"). Это попытка закрыть ранее открытую кавычку и скобку в оригинальном SQL-запросе. Символ % часто используется как подстановочный знак в LIKE-запросах, но здесь он, скорее всего, является частью полезной нагрузки, которая должна нарушить синтаксис. Закрывающая кавычка " и скобка ) позволяют «вырваться» из строкового литерала и добавить собственный код.
Оператор AND
Далее идёт AND — логический оператор, который используется для объединения условий. В контексте инъекции он нужен, чтобы внедряемая функция выполнилась только при истинности предыдущего условия (или просто для сохранения синтаксиса).
Функция EXTRACTVALUE
EXTRACTVALUE(XML_document, XPath_expression) — это встроенная функция MySQL (до версии 8.0.17), предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Она возвращает текст, соответствующий XPath. Если XPath-выражение некорректно, функция генерирует ошибку, в тексте которой может содержаться переданный аргумент. Это и используется для error-based инъекций.
Аргументы функции
Первый аргумент — 8877. Это просто число, которое не является корректным XML-документом. При вызове EXTRACTVALUE с таким аргументом MySQL попытается его разобрать и, скорее всего, выдаст ошибку. Однако суть в другом: второй аргумент — CONCAT(0x7e,((SELECT (ELT(8877=8877,1)))),0x7e) — формирует строку, которая будет включена в сообщение об ошибке.
Функция CONCAT и шестнадцатеричные литералы
CONCAT объединяет строки. Здесь она соединяет три части:
0x7e— шестнадцатеричное представление символа~(тильда).- Результат подзапроса
(SELECT (ELT(8877=8877,1))). - Снова
0x7e— закрывающая тильда.
Тильда используется как маркер, чтобы в сообщении об ошибке легко было найти внедрённые данные.
Подзапрос с ELT
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(8877=8877,1) — условие 8877=8877 всегда истинно, что даёт 1 (в MySQL true = 1). Значит, ELT вернёт первый элемент — 1. Это простейшая проверка, которая всегда возвращает 1. В реальной атаке вместо 1 мог бы быть, например, CONCAT(username,0x3a,password) из таблицы users.
Комментарий -- -
В конце стоит -- -. Двойной дефис с пробелом — это комментарий в SQL, который игнорирует всё, что идёт после него. Пробел после -- обязателен в некоторых СУБД, включая MySQL. Это позволяет отсечь остаток оригинального запроса.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM articles WHERE title = '...'После подстановки полезной нагрузки запрос станет:
SELECT * FROM articles WHERE title = '%") AND EXTRACTVALUE(8877,CONCAT(0x7e,((SELECT (ELT(8877=8877,1)))),0x7e))-- -'MySQL выполнит функцию EXTRACTVALUE. Поскольку первый аргумент не является корректным XML, возникнет ошибка вида:
XPATH syntax error: '~1~'
В сообщении об ошибке появятся данные, переданные во втором аргументе. В нашем случае это ~1~. Если бы вместо 1 стоял подзапрос, извлекающий логин и пароль, они бы также отобразились в ошибке.
Цели и опасность
Такая инъекция позволяет атакующему:
- Получить версию СУБД, имя базы данных, имя пользователя.
- Извлечь содержимое таблиц, включая учётные данные.
- В некоторых случаях — выполнить произвольные команды на сервере (при наличии соответствующих привилегий).
Error-based инъекции особенно опасны, потому что не требуют слепого перебора и дают немедленный результат в ответе сервера.
Меры защиты
Чтобы предотвратить подобные атаки, необходимо:
- Использовать параметризованные запросы (prepared statements) — это самый надёжный способ.
- Применять ORM, которые автоматически экранируют опасные символы.
- Проводить валидацию и санитизацию всех входных данных.
- Ограничить права пользователя БД, чтобы даже при успешной инъекции ущерб был минимальным.
- Обновить MySQL до версии 8.0.17 или выше, где функции EXTRACTVALUE и UPDATEXML удалены.
Заключение
Рассмотренная строка — яркий пример эксплуатации ошибок СУБД для извлечения данных. Понимание механики таких атак помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Если вы встретили подобную строку в логах, это сигнал о попытке взлома, и следует немедленно проверить безопасность кода.
Комментарии
—Войдите, чтобы оставить комментарий