Что такое error-based SQL-инъекция через EXTRACTVALUE
Строка )))) AND EXTRACTVALUE(8352,CONCAT(0x7e,((SELECT (ELT(8352=8352,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции для СУБД MySQL. Эта техника позволяет злоумышленнику извлекать данные из базы данных, заставляя сервер выводить их в сообщении об ошибке. В данном случае используется функция EXTRACTVALUE, которая предназначена для работы с XML и генерирует ошибку XPath при некорректном втором аргументе.
Подобные инъекции часто встречаются в уязвимых веб-приложениях, где пользовательский ввод не фильтруется должным образом. Понимание механики таких атак помогает разработчикам и специалистам по безопасности эффективно защищать системы.
Разбор структуры запроса
Рассмотрим каждый элемент подробнее.
Начальные символы ))))
Четыре закрывающие скобки обычно используются для завершения ранее открытых скобок в оригинальном SQL-запросе, который модифицирует атакующий. Это позволяет внедрить свой код в существующее выражение, не нарушая его синтаксис.
Оператор AND
Логический оператор AND присоединяет вредоносное условие к исходному запросу. Если исходный запрос был истинным, добавление AND ... заставит СУБД вычислить и правую часть.
Функция EXTRACTVALUE(8352, ...)
EXTRACTVALUE — это встроенная функция MySQL, которая извлекает значение из фрагмента XML, используя выражение XPath. Синтаксис: EXTRACTVALUE(XML_frag, XPath_expr). Если XPath-выражение некорректно, MySQL возвращает ошибку с текстом, содержащим переданное значение. Это и эксплуатируется.
Первый аргумент: 8352
Число 8352 — произвольный идентификатор, который не несёт смысловой нагрузки. Он просто передаётся как XML-фрагмент. Важно, чтобы он был допустимым, иначе ошибка возникнет раньше.
Второй аргумент: CONCAT(0x7e, ((SELECT (ELT(8352=8352,1)))), 0x7e)
Здесь формируется строка, которая будет использована как XPath-выражение. 0x7e — это шестнадцатеричное представление символа ~ (тильда). CONCAT объединяет тильду, результат подзапроса и ещё одну тильду. Тильды служат маркерами, чтобы облегчить извлечение данных из сообщения об ошибке.
Подзапрос (SELECT (ELT(8352=8352,1)))
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(8352=8352, 1): условие 8352=8352 всегда истинно, что в MySQL даёт 1. Таким образом, ELT(1, 1) возвращает строку '1'. Подзапрос SELECT извлекает это значение. В реальной атаке вместо 1 могло бы быть имя таблицы, версия СУБД или другие данные, полученные через подзапрос.
Завершение -- -
Двойной дефис с пробелом — это комментарий в SQL, который отсекает оставшуюся часть оригинального запроса, чтобы не возникло синтаксической ошибки.
Как работает извлечение данных
Когда MySQL выполняет EXTRACTVALUE(8352, CONCAT(0x7e, (SELECT ...), 0x7e)), второй аргумент становится строкой вида ~1~ (если подзапрос вернул 1). Эта строка не является корректным XPath-выражением, поэтому MySQL генерирует ошибку:
ERROR 1105 (HY000): XPATH syntax error: '~1~'
В тексте ошибки отображается переданная строка. Если вместо 1 подставить, например, SELECT version(), то в ошибке появится версия сервера. Так злоумышленник может пошагово извлекать любые данные: имена таблиц, столбцов, логины, пароли и т.д.
Этот метод называется error-based SQL injection, потому что данные возвращаются через сообщения об ошибках. Он особенно эффективен, когда приложение выводит ошибки СУБД на экран или в логи, доступные атакующему.
Пример практического использования
Предположим, есть уязвимый параметр id в URL: http://example.com/product.php?id=1. Оригинальный запрос может выглядеть так:
SELECT * FROM products WHERE id = 1;
Атакующий подставляет:
1)))) AND EXTRACTVALUE(8352,CONCAT(0x7e,((SELECT (ELT(8352=8352,1)))),0x7e))-- -
Итоговый запрос:
SELECT * FROM products WHERE id = 1)))) AND EXTRACTVALUE(8352,CONCAT(0x7e,((SELECT (ELT(8352=8352,1)))),0x7e))-- -;
Четыре закрывающие скобки могут закрывать скобки, которые использовались в оригинальном запросе (например, если было WHERE id = (1)). В данном примере они могут быть избыточны, но в реальных условиях подбираются под конкретный запрос.
В результате выполнения MySQL вернёт ошибку с текстом ~1~, что подтвердит уязвимость. Далее атакующий заменяет 1 на подзапросы, извлекающие нужные данные.
Меры защиты от error-based SQL-инъекций
Чтобы предотвратить такие атаки, необходимо применять комплекс мер:
- Использование подготовленных выражений (prepared statements). Это самый надёжный способ, при котором данные передаются отдельно от SQL-кода и не могут изменить структуру запроса.
- Экранирование специальных символов. Если подготовленные выражения недоступны, следует тщательно экранировать все пользовательские данные, особенно кавычки и обратные слэши.
- Валидация ввода. Проверка типов данных (например, что
id— целое число) снижает риск инъекций. - Отключение вывода ошибок СУБД. Настройка
display_errors = Offв PHP или аналогичные настройки в других языках, чтобы сообщения об ошибках не попадали к пользователю. - Принцип наименьших привилегий. Учётная запись, используемая приложением для подключения к БД, должна иметь минимально необходимые права.
- Регулярное обновление СУБД. В новых версиях MySQL некоторые функции могут быть удалены или изменены, что снижает риск.
Заключение
Строка )))) AND EXTRACTVALUE(8352,CONCAT(0x7e,((SELECT (ELT(8352=8352,1)))),0x7e))-- - — это не просто набор символов, а рабочий инструмент для эксплуатации уязвимостей. Понимание принципов его работы помогает как специалистам по безопасности, так и разработчикам создавать более защищённые приложения. Помните, что безопасность — это процесс, а не одноразовое действие.
Комментарии
—Войдите, чтобы оставить комментарий