Что такое SQL-инъекция с EXTRACTVALUE и ELT?
Представленный запрос %') AND EXTRACTVALUE(1799,CONCAT(0x7e,((SELECT (ELT(1799=1799,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Такие атаки используют функции, генерирующие ошибки с внедрёнными данными, чтобы извлечь информацию из базы данных через сообщения об ошибках, возвращаемые приложением.
В данном случае злоумышленник пытается проверить возможность инъекции и, в случае успеха, получить данные. Давайте разберём каждый элемент запроса.
Анатомия инъекции
1. Начало: %')
Символы %') предназначены для «разрыва» оригинального SQL-запроса. Часто они используются, чтобы закрыть строковый литерал и скобку в уязвимом запросе, например: SELECT * FROM users WHERE name = '%'). Добавляя %'), атакующий пытается сделать синтаксис корректным для внедрения своего кода.
2. Функция EXTRACTVALUE()
EXTRACTVALUE(XML_document, XPath_expression) — встроенная функция MySQL, которая извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно или возвращает несколько узлов, MySQL генерирует ошибку, содержащую переданные данные. Это и используется для внедрения.
В нашем запросе: EXTRACTVALUE(1799, CONCAT(0x7e, (SELECT (ELT(1799=1799,1))), 0x7e)). Первый аргумент — число 1799 (может быть любым, часто используется случайное число для уникальности ошибки). Второй аргумент — XPath-выражение, формируемое динамически.
3. CONCAT и 0x7e
0x7e — шестнадцатеричное представление символа ~ (тильда). CONCAT(0x7e, ..., 0x7e) оборачивает извлекаемые данные в тильды, чтобы их было легко найти в тексте ошибки. Например, ошибка может выглядеть так: XPATH syntax error: '~1~'.
4. ELT() и логическое выражение
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(1799=1799, 1): выражение 1799=1799 истинно (1), поэтому возвращается первый элемент — строка '1'. Если бы условие было ложным (0), ELT вернул бы NULL. Это простой способ проверить, выполняется ли условие, и внедрить результат в ошибку.
Таким образом, SELECT (ELT(1799=1799,1)) возвращает '1', затем CONCAT добавляет тильды, и EXTRACTVALUE пытается использовать строку '~1~' как XPath. Поскольку это невалидный XPath, генерируется ошибка, содержащая '~1~'. Если приложение выводит ошибки БД, атакующий увидит этот результат.
Цель атаки
В данном конкретном запросе злоумышленник просто проверяет работоспособность инъекции: он использует заведомо истинное условие 1799=1799, чтобы получить предсказуемый результат '1'. Если ошибка появится, значит, инъекция возможна, и можно переходить к извлечению реальных данных, подставляя вместо ELT(1799=1799,1) подзапросы, например (SELECT password FROM users LIMIT 1).
Подобные техники часто используются в инструментах автоматизации, таких как sqlmap, для дампа баз данных.
Как защититься от таких инъекций?
Основная причина уязвимости — недостаточная фильтрация пользовательского ввода и конкатенация его в SQL-запрос. Вот ключевые меры защиты:
- Используйте параметризованные запросы (prepared statements). Это самый надёжный способ: данные передаются отдельно от SQL-кода и не могут изменить структуру запроса.
- Экранируйте специальные символы. Если по какой-то причине нельзя использовать подготовленные выражения, применяйте функции экранирования (например,
mysqli_real_escape_stringв PHP). - Ограничьте права пользователя БД. Приложение должно подключаться к базе с минимально необходимыми привилегиями, чтобы даже при успешной инъекции злоумышленник не смог получить лишние данные.
- Отключите вывод ошибок БД в продакшене. Сообщения об ошибках не должны отображаться пользователям; логируйте их на сервере.
- Используйте WAF (Web Application Firewall). Современные WAF могут блокировать известные паттерны SQL-инъекций, включая EXTRACTVALUE.
- Регулярно обновляйте СУБД и приложения. В новых версиях MySQL некоторые опасные функции могут быть отключены или ограничены.
Важно понимать, что EXTRACTVALUE и подобные функции (например, UPDATEXML) не являются уязвимостями сами по себе — они лишь инструменты, которые становятся опасными при неправильной обработке ввода.
Заключение
Запрос %') AND EXTRACTVALUE(1799,CONCAT(0x7e,((SELECT (ELT(1799=1799,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции, использующей особенности MySQL для извлечения данных через сообщения об ошибках. Понимание механики таких атак помогает разработчикам создавать более безопасные приложения. Главный вывод: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий