Что такое EXTRACTVALUE и при чём тут SQL-инъекция
Функция EXTRACTVALUE — это встроенная функция MySQL (и MariaDB), предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression). Она возвращает текст содержимого XML-фрагмента, соответствующего XPath. Однако при некорректном XPath функция генерирует ошибку, и именно это свойство активно используется злоумышленниками для проведения так называемых error-based SQL-инъекций.
В вашем запросе: ") AND EXTRACTVALUE(1616,CONCAT(0x7e,((SELECT (ELT(1616=1616,1)))),0x7e))-- - — это классический пример эксплуатации уязвимости через функцию EXTRACTVALUE. Давайте разберём его по частям.
Структура инъекционного запроса
Запрос начинается с ") — это попытка закрыть предыдущее выражение в уязвимом SQL-запросе, чтобы внедрить свой код. Далее идёт AND EXTRACTVALUE(...), что добавляет условие к оригинальному запросу. В конце -- - — это комментарий, который отсекает оставшуюся часть оригинального SQL-запроса, чтобы не вызвать синтаксическую ошибку.
Внутри EXTRACTVALUE первым аргументом передаётся число 1616 (произвольный XML-документ, который не является корректным XML, но это не важно — важно, что второй аргумент вызывает ошибку). Второй аргумент — CONCAT(0x7e, ((SELECT (ELT(1616=1616,1)))), 0x7e).
0x7e— это шестнадцатеричное представление символа тильды~. Он используется как маркер, чтобы в сообщении об ошибке было легко найти внедрённые данные.ELT(1616=1616, 1)— функция ELT возвращает N-й элемент из списка. Здесь1616=1616— это истинное выражение, которое в MySQL возвращает 1. Таким образом, ELT(1, 1) вернёт 1. Это простейший пример, демонстрирующий возможность внедрения произвольного выражения. На практике вместо1616=1616подставляется подзапрос, извлекающий данные (например, имя пользователя, хеш пароля, версию СУБД).CONCATобъединяет тильды и результат подзапроса в одну строку.
Когда MySQL пытается вычислить EXTRACTVALUE с некорректным XPath (а строка, содержащая тильды и произвольные символы, не является валидным XPath), возникает ошибка вида: XPATH syntax error: '~1~'. В этом сообщении об ошибке и «утекают» данные, которые злоумышленник внедрил в XPath. Если вместо 1 подставить, например, (SELECT user()), то в ошибке отобразится имя текущего пользователя БД.
Зачем нужна такая инъекция
Error-based SQL-инъекции через EXTRACTVALUE (и аналогичную функцию UPDATEXML) позволяют атакующему извлекать информацию из базы данных, даже если приложение не выводит результаты запроса напрямую. Достаточно, чтобы сообщения об ошибках СУБД отображались на странице или возвращались в ответе. Это один из самых эффективных методов слепой эксплуатации, когда другие каналы (UNION, boolean-based) недоступны.
Основные цели:
- Получение версии MySQL/MariaDB.
- Извлечение имён таблиц и колонок из
information_schema. - Чтение конфиденциальных данных: логины, пароли, персональная информация.
- В некоторых случаях — выполнение произвольных команд через
INTO OUTFILE.
Пример реальной эксплуатации
Предположим, уязвимый параметр — id в URL: https://example.com/product?id=1. Оригинальный запрос: SELECT * FROM products WHERE id = '1'. Внедряем:
1" AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))-- -
В ответе сервера появится ошибка: XPATH syntax error: '~shop_db~'. Так узнаём имя текущей базы данных. Далее можно извлекать таблицы:
1" AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT table_name FROM information_schema.tables WHERE table_schema=database() LIMIT 0,1), 0x7e))-- -
И так далее, пока не будут получены все нужные данные. Ограничение длины вывода (обычно 32 символа) обходится с помощью SUBSTRING или MID.
Меры защиты
Чтобы предотвратить подобные атаки, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией. Это самый надёжный способ, так как данные не интерпретируются как SQL-код.
- Экранировать специальные символы при невозможности использовать параметризацию. Но помните, что экранирование не всегда спасает, если кодировка соединения настроена неверно.
- Отключить вывод ошибок СУБД на продакшене. Ошибки должны логироваться, но не показываться пользователю.
- Ограничить права пользователя БД, от имени которого работает приложение. Не давайте ему доступ к
information_schemaбез необходимости и тем более к файловой системе. - Регулярно обновлять СУБД и применять патчи безопасности.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов, хотя это не панацея.
Важно: даже если приложение не выводит ошибки, злоумышленник может использовать time-based или boolean-based слепые инъекции. Поэтому защита должна быть комплексной.
Заключение
Запрос ") AND EXTRACTVALUE(1616,CONCAT(0x7e,((SELECT (ELT(1616=1616,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции через функцию EXTRACTVALUE. Он демонстрирует, как с помощью намеренно вызванной ошибки XPath можно извлечь произвольные данные из базы. Понимание этого механизма необходимо как специалистам по безопасности для тестирования, так и разработчикам для написания защищённого кода. Помните: лучшая защита — параметризованные запросы и минимизация привилегий.
Комментарии
—Войдите, чтобы оставить комментарий