Что такое SQL-инъекция через ExtractValue?
SQL-инъекция остаётся одной из самых опасных уязвимостей веб-приложений. Согласно OWASP Top 10, она входит в список критических рисков. Один из методов эксплуатации — error-based SQL-инъекция с использованием функции EXTRACTVALUE() в MySQL. Этот приём позволяет злоумышленнику извлекать данные из базы, вызывая ошибки, которые выводятся на страницу.
Функция EXTRACTVALUE(XML_fragment, XPath_expression) извлекает значение из XML-строки по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL возвращает ошибку с текстом, содержащим переданные данные. Это и используется для получения информации.
Синтаксис и принцип работы
Рассмотрим запрос из вашего вопроса:
%' OR EXTRACTVALUE(4210,CONCAT(0x7e,((SELECT (ELT(4210=4210,1)))),0x7e))-- -
Разберём его по частям:
%'— закрывает строковый литерал в уязвимом параметре.OR— логический оператор для внедрения условия.EXTRACTVALUE(4210, ...)— первый аргумент — произвольное число (4210), второй — XPath-выражение, которое вызывает ошибку.CONCAT(0x7e, ..., 0x7e)— объединяет тильды (~) с результатом подзапроса. Тильды помогают отделить данные в сообщении об ошибке.(SELECT (ELT(4210=4210,1)))— подзапрос, возвращающий 1, если условие истинно.ELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь4210=4210всегда истинно, поэтому возвращается 1.-- -— комментарий, обрезающий остаток запроса.
В результате MySQL пытается выполнить XPath-выражение ~1~, что не является допустимым XPath, и возвращает ошибку вида: XPATH syntax error: '~1~'. На странице отобразится этот текст, подтверждая наличие инъекции.
Как эксплуатируется error-based SQLi
Главная цель — заставить базу данных вернуть нужные данные в сообщении об ошибке. Вместо константы 1 в подзапрос подставляются имена таблиц, колонок или конкретные значения. Например, для получения имени текущей базы данных:
%' OR EXTRACTVALUE(1,CONCAT(0x7e,(SELECT database()),0x7e))-- -
Ошибка покажет: XPATH syntax error: '~имя_базы~'. Аналогично можно извлечь версию MySQL, имя пользователя, названия таблиц из information_schema.tables и даже хеши паролей.
Для посимвольного извлечения данных применяют функции SUBSTRING() и LIMIT. Например, чтобы получить имя первой таблицы:
%' OR EXTRACTVALUE(1,CONCAT(0x7e,(SELECT table_name FROM information_schema.tables LIMIT 0,1),0x7e))-- -
Меняя значение LIMIT (0,1 → 1,1 и т.д.), перебирают все таблицы.
Ограничения и альтернативы
Метод EXTRACTVALUE работает только в MySQL и MariaDB до версии 5.7 включительно. В более новых версиях (MySQL 8.0+) функция EXTRACTVALUE удалена, и error-based инъекции через неё невозможны. Однако существуют другие функции, вызывающие ошибки с данными: UPDATEXML(), GTID_SUBSET(), JSON_KEYS() и т.д.
Если приложение не выводит ошибки базы данных, злоумышленник может использовать blind SQL-инъекции (boolean-based или time-based), которые медленнее, но тоже эффективны.
Пример реальной атаки
Предположим, сайт имеет параметр id=1 и уязвим. Злоумышленник отправляет:
id=1' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT user()),0x7e))-- -
В ответе появляется ошибка с именем пользователя БД, например ~admin@localhost~. Затем атакующий перебирает таблицы, колонки и извлекает логины/пароли. Это может привести к полному захвату сайта.
Как защититься от SQL-инъекций
Основной метод — использование параметризованных запросов (prepared statements). Они разделяют код и данные, поэтому внедрение команд невозможно. В PHP это PDO или mysqli с подготовленными выражениями, в Java — PreparedStatement, в Python — параметризованные курсоры.
- Валидация входных данных: проверяйте типы, форматы, белые списки допустимых значений.
- Экранирование: используйте функции экранирования спецсимволов, но это менее надёжно, чем параметризация.
- Минимальные привилегии: учётная запись БД для веб-приложения не должна иметь прав на чтение системных таблиц или выполнение опасных операций.
- Отключение вывода ошибок: не показывайте пользователям сообщения СУБД, логируйте их на сервере.
- WAF: веб-приложения-экраны могут блокировать подозрительные запросы, но не заменяют исправление кода.
Регулярно проводите аудит кода и пентесты, чтобы выявлять уязвимости до злоумышленников.
Вывод
Конструкция %' OR EXTRACTVALUE(...)-- - — классический пример error-based SQL-инъекции в MySQL. Она позволяет быстро извлекать данные через сообщения об ошибках. Понимание этого метода помогает разработчикам осознать важность параметризованных запросов и других мер защиты. Никогда не доверяйте пользовательскому вводу и всегда используйте безопасные API для работы с базами данных.
Комментарии
—Войдите, чтобы оставить комментарий