Что такое SQL-инъекция через ExtractValue?
SQL-инъекция — один из самых распространённых и опасных видов атак на веб-приложения. Злоумышленник внедряет вредоносный SQL-код в запросы к базе данных, что позволяет читать, изменять или удалять конфиденциальную информацию. Среди множества техник особое место занимает error-based SQL-инъекция, при которой хакер извлекает данные через сообщения об ошибках, возвращаемые сервером базы данных.
Функция EXTRACTVALUE() в MySQL предназначена для работы с XML-документами: она извлекает значение из XML-строки по заданному XPath-выражению. Однако при неправильной обработке пользовательского ввода эта функция может стать инструментом атаки. Если в XPath попадает непредвиденный символ, MySQL генерирует ошибку, в тексте которой отображается переданное значение. Злоумышленники используют это для вывода данных, которые в обычных условиях недоступны.
Разбор конкретного запроса
Рассмотрим строку, которая часто встречается в логах веб-серверов и отчётах систем обнаружения вторжений:
)))) AND EXTRACTVALUE(6322,CONCAT(0x7e,((SELECT (ELT(6322=6322,1)))),0x7e))-- -
Это классический пример error-based SQL-инъекции. Разберём его по частям:
))))— несколько закрывающих скобок, которые используются для «обрыва» исходного SQL-запроса и приведения его к синтаксически корректному виду после внедрения.AND— логический оператор, присоединяющий вредоносное условие к оригинальному запросу.EXTRACTVALUE(6322, CONCAT(...))— вызов уязвимой функции. Первый аргумент (6322) — произвольное число, второй — XPath-выражение, формируемое динамически.CONCAT(0x7e, ((SELECT (ELT(6322=6322,1)))), 0x7e)— конкатенация символа тильды (0x7e— шестнадцатеричное представление~), результата подзапроса и ещё одной тильды. Тильда добавляется, чтобы гарантировать синтаксическую ошибку XPath, так как символ~недопустим в начале XPath-выражения.SELECT (ELT(6322=6322,1))— подзапрос, возвращающий значение.ELT()выбирает N-й элемент из списка. Здесь условие6322=6322всегда истинно, поэтому возвращается первый элемент —1. В реальной атаке на месте этого подзапроса стояло бы извлечение имени базы данных, таблицы или хеша пароля.-- -— комментарий, который «отрезает» оставшуюся часть оригинального запроса, чтобы не возникло ошибок синтаксиса.
Таким образом, при выполнении этого кода MySQL попытается вычислить XPath-выражение, начинающееся с тильды, что вызовет ошибку вида: XPATH syntax error: '~1~'. В сообщении об ошибке злоумышленник увидит результат подзапроса — в данном случае 1. Меняя подзапрос, атакующий может посимвольно извлекать любые данные из базы.
Почему это работает?
Уязвимость возникает, когда веб-приложение передаёт в SQL-запрос пользовательские данные без должной обработки. Функция EXTRACTVALUE не предназначена для вывода данных в ошибках, но её поведение при некорректном XPath предсказуемо: MySQL включает переданное значение в текст ошибки. Это позволяет обойти ограничения, когда приложение не отображает результаты запроса напрямую, но выводит сообщения об ошибках.
Подобные техники также используют функции UPDATEXML() и GTID_SUBSET(). Все они относятся к классу error-based SQL-инъекций и активно применяются в инструментах автоматизации, например, в sqlmap.
Последствия успешной атаки
Если злоумышленнику удаётся эксплуатировать уязвимость, он может:
- получить доступ к учётным данным пользователей, включая логины и хеши паролей;
- извлечь персональные данные клиентов, номера банковских карт, адреса;
- изменить или удалить информацию в базе;
- получить контроль над сервером базы данных, если у учётной записи достаточно прав;
- использовать скомпрометированный сервер для дальнейших атак.
По данным OWASP, инъекции (включая SQL) остаются в топ-10 критических угроз веб-приложений. Ущерб от успешной атаки может исчисляться миллионами рублей из-за утечек данных и штрафов регуляторов.
Как защититься от error-based SQL-инъекций
Основной метод защиты — использование параметризованных запросов (prepared statements). При этом SQL-код и данные передаются раздельно, поэтому пользовательский ввод никогда не интерпретируется как часть запроса. Дополнительные меры:
- Валидация и фильтрация входных данных. Проверяйте все входящие параметры на соответствие ожидаемому формату. Например, если параметр должен быть числом, преобразуйте его к целому типу.
- Экранирование специальных символов. Если параметризация невозможна, используйте функции экранирования, предоставляемые драйвером базы данных (например,
mysqli_real_escape_stringв PHP). - Отключение вывода ошибок в production. Сообщения об ошибках базы данных не должны попадать в ответ клиенту. Логируйте их на сервере, а пользователю показывайте общую страницу ошибки.
- Принцип наименьших привилегий. Учётная запись, от имени которой работает веб-приложение, должна иметь только необходимые права. Не используйте root для подключения из кода.
- Регулярное обновление СУБД и фреймворков. Производители выпускают патчи для известных уязвимостей.
- Использование WAF. Веб-приложения-экраны могут блокировать подозрительные запросы, содержащие характерные сигнатуры SQL-инъекций.
Также рекомендуется проводить регулярные аудиты безопасности и сканирования уязвимостей, чтобы выявлять проблемы до того, как ими воспользуются злоумышленники.
Заключение
Запрос )))) AND EXTRACTVALUE(6322,CONCAT(0x7e,((SELECT (ELT(6322=6322,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции через функцию ExtractValue в MySQL. Он демонстрирует, как злоумышленники используют особенности обработки ошибок для извлечения данных. Понимание механизма работы таких атак помогает разработчикам и администраторам правильно выстраивать защиту. Главное правило — никогда не доверять пользовательскому вводу и всегда использовать параметризованные запросы. Безопасность базы данных — это не разовое мероприятие, а постоянный процесс.
Комментарии
—Войдите, чтобы оставить комментарий