Что такое OR EXTRACTVALUE в SQL-инъекциях
Строка OR EXTRACTVALUE(4781,CONCAT(0x7e,((SELECT (ELT(4781=4781,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через сообщения об ошибках, которые возвращает сервер. Злоумышленник внедряет вредоносный код в параметры запроса, и если приложение не фильтрует ввод, база данных выполняет этот код и выдаёт результат в тексте ошибки.
В данном случае применяется функция EXTRACTVALUE(), предназначенная для работы с XML. Она извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, в которой отображается переданная строка. Это и позволяет атакующему «вытащить» нужные данные.
Разбор конструкции по частям
Давайте разберём каждый элемент запроса:
OR— логический оператор, который добавляется к оригинальному SQL-запросу, чтобы обойти условия и внедрить свою функцию.EXTRACTVALUE(4781, CONCAT(...))— вызов функции. Первый аргумент (4781) — произвольное число, которое не влияет на результат, но требуется синтаксисом. Второй аргумент — строка, передаваемая в XPath.CONCAT(0x7e, ((SELECT (ELT(4781=4781,1)))), 0x7e)— конкатенация символов.0x7e— это шестнадцатеричное представление символа тильды (~). Он используется как разделитель, чтобы облегчить поиск выводимых данных в сообщении об ошибке.SELECT (ELT(4781=4781,1))— подзапрос, возвращающий результат функцииELT().ELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь N — это4781=4781, что всегда истинно (1), поэтому возвращается первая строка — «1». В реальной атаке на месте этой единицы был бы другой подзапрос, извлекающий данные (например, имя пользователя, хеш пароля).-- -— комментарий, который отсекает оставшуюся часть оригинального запроса, чтобы синтаксис оставался корректным.
Как работает error-based инъекция через EXTRACTVALUE
Функция EXTRACTVALUE(XML_document, XPath_expression) в MySQL анализирует XPath. Если выражение начинается с символа, который не является допустимым (например, с тильды), MySQL выдаёт ошибку вида:
XPATH syntax error: '~1~'
В этом сообщении отображается переданная строка. Атакующий может подставить в подзапрос любой SQL-запрос, и результат его выполнения попадёт в текст ошибки. Так можно посимвольно извлекать данные из базы: имена таблиц, столбцов, логины, пароли и другую конфиденциальную информацию.
Конструкция ELT(4781=4781,1) в данном примере — это простейшая демонстрация. В реальной атаке вместо 1 могло бы быть, например, (SELECT password FROM users LIMIT 1). Тогда в ошибке появился бы пароль.
Зачем нужны 0x7e и CONCAT
Символ 0x7e (тильда) добавляется по краям извлекаемых данных, чтобы их было легко найти в сообщении об ошибке. Без разделителей сложно отделить полезную нагрузку от остального текста ошибки. CONCAT просто склеивает тильду, результат подзапроса и ещё одну тильду в одну строку.
Иногда вместо 0x7e используют 0x3a (двоеточие) или другие символы, которые гарантированно вызовут ошибку XPath. Главное — чтобы символ не был допустимым началом XPath-выражения.
Опасность и последствия
Error-based SQL-инъекции через EXTRACTVALUE (а также через UPDATEXML) — один из самых быстрых способов извлечения данных. В отличие от blind-инъекций, где приходится задавать множество запросов, здесь результат приходит сразу в ответе сервера. Это делает атаку очень эффективной.
Последствия успешной эксплуатации могут быть катастрофическими:
- Утечка учётных данных пользователей (логины, пароли, токены).
- Получение доступа к административной панели.
- Чтение и изменение любых данных в базе.
- В некоторых случаях — выполнение команд на сервере (при наличии соответствующих привилегий).
Как защититься от таких инъекций
Основной метод защиты — использование параметризованных запросов (prepared statements). Они разделяют код SQL и данные, поэтому внедрённые строки не интерпретируются как SQL-код. Это самый надёжный способ.
Дополнительные меры:
- Валидация и фильтрация входных данных: проверяйте все параметры, которые попадают в SQL-запросы, на соответствие ожидаемому формату (числа, даты, строки без спецсимволов).
- Экранирование специальных символов: если параметризацию применить невозможно, используйте функции экранирования, предоставляемые драйвером БД (например,
mysqli_real_escape_stringв PHP). - Ограничение привилегий пользователя БД: учётная запись, от имени которой работает приложение, не должна иметь прав на чтение системных таблиц или выполнение опасных функций.
- Отключение вывода ошибок на продакшене: сообщения об ошибках БД не должны показываться пользователю. Это не устраняет уязвимость, но затрудняет эксплуатацию error-based инъекций.
- Использование WAF: веб-application firewall может блокировать известные шаблоны атак, хотя и не является панацеей.
Пример безопасного кода
Вместо уязвимого запроса:
$query = "SELECT * FROM users WHERE id = " . $_GET['id'];
Следует использовать параметризованный запрос (пример на PHP с PDO):
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $_GET['id']]);
В этом случае даже если злоумышленник передаст 1 OR EXTRACTVALUE(...), база данных воспримет это как строку и не выполнит внедрённый код.
Заключение
Конструкция OR EXTRACTVALUE(4781,CONCAT(0x7e,((SELECT (ELT(4781=4781,1)))),0x7e))-- - — это типичный эксплойт для error-based SQL-инъекции в MySQL. Она демонстрирует, как через функцию EXTRACTVALUE и подзапрос можно заставить базу данных вывести произвольные данные в сообщении об ошибке. Понимание механизма таких атак помогает разработчикам и специалистам по безопасности правильно выстраивать защиту. Главное правило: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий