Что такое SQL-инъекция через EXTRACTVALUE?
SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Существует несколько типов таких атак: основанные на ошибках (error-based), на времени (time-based), на логических выражениях (boolean-based) и другие. Запрос, который вы видите: ")) OR EXTRACTVALUE(3217,CONCAT(0x7e,((SELECT (ELT(3217=3217,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции, использующей функцию EXTRACTVALUE в СУБД MySQL.
Цель такой инъекции — заставить базу данных вернуть сообщение об ошибке, содержащее полезные данные (например, имя пользователя, версию БД, названия таблиц). Функция EXTRACTVALUE специально провоцирует ошибку формата XPath, и в тексте ошибки MySQL отображает переданное ей значение. Это позволяет атакующему пошагово извлекать информацию из базы.
Как работает функция EXTRACTVALUE
Функция EXTRACTVALUE(XML_fragment, XPath_expression) принимает два строковых аргумента: фрагмент XML-разметки и выражение XPath. Она возвращает текст (CDATA) первого текстового узла, который является дочерним для элемента или элементов, соответствующих XPath-выражению.
Если XPath-выражение некорректно, MySQL генерирует ошибку вида: XPATH syntax error: '...'. В этой ошибке отображается часть переданного XPath-выражения. Злоумышленники пользуются этим, чтобы вывести в сообщении об ошибке результат подзапроса.
Пример: EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)) вернёт ошибку, содержащую версию MySQL, обрамлённую символами тильды (~).
Разбор конкретного запроса
Рассмотрим запрос: ")) OR EXTRACTVALUE(3217,CONCAT(0x7e,((SELECT (ELT(3217=3217,1)))),0x7e))-- -
"))— закрывает предыдущие скобки и кавычки в уязвимом запросе, чтобы внедрить свой код.OR— логический оператор, который делает условие всегда истинным (если подзапрос вернёт что-то).EXTRACTVALUE(3217, ...)— вызов функции для генерации ошибки. Первый аргумент (3217) — произвольное число, не являющееся корректным XML.CONCAT(0x7e, ((SELECT (ELT(3217=3217,1)))), 0x7e)— формирует строку для XPath.0x7e— это шестнадцатеричный код символа тильды (~).ELT(3217=3217,1)— функция ELT возвращает N-й элемент из списка. Здесь условие3217=3217всегда истинно (1), поэтому ELT(1,1) вернёт 1. Это простейший пример, но на практике вместо 1 подставляется подзапрос, извлекающий данные (например,(SELECT user())).-- -— комментарий, обрезающий остаток оригинального SQL-запроса.
В результате выполнения этого запроса MySQL попытается разобрать строку ~1~ как XPath, что вызовет ошибку: XPATH syntax error: '~1~'. В реальной атаке вместо 1 будет, например, database(), и в ошибке отобразится имя текущей базы данных.
Как эксплуатируется уязвимость
Процесс извлечения данных через error-based SQL-инъекцию с EXTRACTVALUE обычно включает несколько шагов:
- Определение точки инъекции. Атакующий проверяет, обрабатывает ли приложение ввод и возвращает ли ошибки СУБД.
- Вывод версии MySQL. Например:
AND EXTRACTVALUE(1, CONCAT(0x7e, version(), 0x7e)). - Получение имени текущей базы данных.
AND EXTRACTVALUE(1, CONCAT(0x7e, database(), 0x7e)). - Извлечение имён таблиц и столбцов. С помощью подзапросов к
information_schema.tablesиinformation_schema.columns. - Дамп данных. Построчный вывод содержимого таблиц с использованием LIMIT и смещения.
Важно: EXTRACTVALUE возвращает не более 32 символов в сообщении об ошибке, поэтому для длинных строк используются функции SUBSTRING или MID.
Другие функции для error-based инъекций
Помимо EXTRACTVALUE, в MySQL часто используются:
UPDATEXML()— аналогична EXTRACTVALUE, но генерирует ошибку через обновление XML.GTID_SUBSET()— в некоторых версиях MySQL позволяет вывести данные в ошибке.EXP()— вызывает ошибку переполнения, если передать большое число.FLOOR(RAND(0)*2)— классический метод с группировкой, вызывающий дублирование ключа.
Однако EXTRACTVALUE и UPDATEXML считаются наиболее удобными, так как позволяют напрямую выводить произвольные строки.
Как защититься от SQL-инъекций
Основной метод защиты — использование параметризованных запросов (prepared statements). Это гарантирует, что пользовательский ввод никогда не интерпретируется как SQL-код. Дополнительные меры:
- Экранирование специальных символов с помощью функций драйвера (например, mysqli_real_escape_string).
- Валидация и фильтрация входных данных по белому списку.
- Минимизация привилегий пользователя БД: не давайте приложению прав на чтение information_schema без необходимости.
- Отключение вывода подробных ошибок СУБД в продакшене (display_errors = off).
- Использование WAF (Web Application Firewall) для блокировки подозрительных запросов.
- Регулярное обновление СУБД и фреймворков.
Если вы проводите тестирование на проникновение, всегда получайте письменное разрешение. Несанкционированный доступ к данным преследуется по закону.
Заключение
Запрос ")) OR EXTRACTVALUE(3217,CONCAT(0x7e,((SELECT (ELT(3217=3217,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции через функцию EXTRACTVALUE. Он демонстрирует, как злоумышленники могут использовать ошибки XPath для извлечения информации из базы данных MySQL. Понимание механизма таких атак помогает разработчикам и специалистам по безопасности своевременно закрывать уязвимости и защищать веб-приложения.
Комментарии
—Войдите, чтобы оставить комментарий