Что такое error-based SQL-инъекция через ExtractValue?
Представленный запрос `) AND EXTRACTVALUE(4608,CONCAT(0x7e,((SELECT (ELT(4608=4608,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции, использующей функцию EXTRACTVALUE в СУБД MySQL. Данная техника позволяет злоумышленнику извлекать данные из базы через сообщения об ошибках, которые возвращает сервер.
Функция EXTRACTVALUE(XML_document, XPath_expression) предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Однако при передаче некорректного XPath-выражения MySQL генерирует ошибку, в тексте которой может содержаться переданная строка. Это и используется для вывода результатов подзапросов.
Разбор структуры запроса
Рассмотрим инъекцию по частям:
`) AND ...-- -— закрытие исходного выражения (например, скобки и кавычки), добавление условия AND и комментария для отсечения остатка запроса.EXTRACTVALUE(4608, CONCAT(0x7e, ((SELECT (ELT(4608=4608,1)))), 0x7e))— вызов функции с двумя аргументами: первый (4608) — произвольное число, второй — конкатенация тильды (0x7e), результата подзапроса и снова тильды.ELT(4608=4608,1)— функция ELT возвращает N-й элемент из списка. Здесь условие4608=4608всегда истинно (1), поэтому ELT(1,1) вернёт 1. В реальной атаке на этом месте был бы подзапрос, извлекающий данные (например, имя таблицы или хеш пароля).
В результате MySQL попытается разобрать строку ~1~ как XPath, что вызовет ошибку вида XPATH syntax error: '~1~'. Злоумышленник видит эту ошибку в ответе сервера и может подставлять в подзапрос любые данные, которые нужно извлечь.
Как это работает на практике
Обычно атака строится так:
- Определяется количество столбцов в исходном запросе (ORDER BY или UNION SELECT).
- Находится уязвимый параметр, который подставляется в SQL-запрос без экранирования.
- В параметр внедряется конструкция с EXTRACTVALUE, где в подзапросе указывается, что именно нужно вытащить: версию СУБД, имя текущей базы, таблицы, столбцы, логины и пароли пользователей.
- Сервер возвращает ошибку, содержащую запрошенные данные, которые злоумышленник читает в HTTP-ответе.
Например, чтобы получить имя текущей базы данных, инъекция может выглядеть так:
`) AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))-- -
В ответе придёт ошибка с названием базы. Далее аналогично извлекаются таблицы, столбцы и записи.
Почему используется именно ExtractValue?
MySQL поддерживает несколько функций, провоцирующих ошибки с выводом данных: EXTRACTVALUE, UPDATEXML, GTID_SUBSET и другие. ExtractValue удобна тем, что она принимает два аргумента, и второй можно сформировать динамически через CONCAT. Это позволяет вставлять произвольные подзапросы и получать их результат в тексте ошибки.
Ограничение: длина выводимой строки обычно не превышает 32 символа (зависит от версии MySQL). Поэтому для извлечения длинных значений используют посимвольный вывод через SUBSTRING или LIMIT.
Примеры реальных атак
В отчётах по пентесту часто описывают эксплуатацию error-based SQLi через XPATH. Например, при тестировании веб-приложения находят параметр id=1, который подставляется в запрос SELECT * FROM users WHERE id = '$id'. Передав 1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))-- -, получают версию MySQL в ошибке.
Далее можно извлечь имена таблиц:
1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1), 0x7e))-- -
И так далее, пока не будут получены все нужные данные.
Как защититься от error-based SQL-инъекций
Основные меры защиты:
- Использование подготовленных выражений (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не попадают в тело SQL-запроса.
- Экранирование специальных символов с помощью функций вроде
mysqli_real_escape_string(но это менее надёжно, чем параметризация). - Валидация входных данных по белому списку (например, только цифры для числовых параметров).
- Отключение вывода подробных ошибок в production-окружении. Ошибки СУБД не должны попадать в ответ клиенту.
- Использование ORM, которые по умолчанию применяют параметризацию.
- Регулярные аудиты безопасности и сканирование уязвимостей.
Также рекомендуется ограничить права пользователя БД, от имени которого работает приложение: запретить доступ к information_schema, если он не нужен, и использовать отдельного пользователя с минимальными привилегиями.
Заключение
Запрос `) AND EXTRACTVALUE(4608,CONCAT(0x7e,((SELECT (ELT(4608=4608,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции через функцию ExtractValue. Понимание таких техник необходимо специалистам по информационной безопасности для тестирования приложений на проникновение и последующего устранения уязвимостей. Разработчикам же следует всегда использовать параметризованные запросы, чтобы исключить саму возможность подобных атак.
Комментарии
—Войдите, чтобы оставить комментарий