Что такое SQL-инъекция через EXTRACTVALUE?
SQL-инъекция — один из самых распространённых способов взлома веб-приложений. Злоумышленник внедряет вредоносный SQL-код в запрос, чтобы получить доступ к базе данных. Особый интерес представляет error-based SQL-инъекция, при которой хакер заставляет сервер выдать сообщение об ошибке, содержащее конфиденциальные данные.
Функция EXTRACTVALUE() в MySQL предназначена для извлечения значения из XML-документа по заданному XPath-выражению. Однако при неправильной обработке пользовательского ввода она становится мощным инструментом для атак. Если в XPath-выражении встречается недопустимый символ, MySQL генерирует ошибку с фрагментом этого выражения. Злоумышленник может подставить в XPath результат подзапроса, и сервер сам «расскажет» ему нужные данные.
Пример уязвимого запроса: SELECT * FROM users WHERE id = 1 AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e));
В ответе появится ошибка вида XPATH syntax error: '~5.7.23~', где 5.7.23 — версия СУБД. Так по крупицам можно вытащить имена таблиц, столбцов, логины и пароли.
Разбор конкретного запроса
Рассмотрим строку из запроса пользователя:
))) AND EXTRACTVALUE(7494,CONCAT(0x7e,((SELECT (ELT(7494=7494,1)))),0x7e))-- -
Это классический пример error-based SQL-инъекции для MySQL. Разберём её по частям:
- ))) — закрывающие скобки, которые «подгоняют» синтаксис исходного запроса, чтобы внедряемая конструкция оказалась валидной.
- AND — логический оператор, присоединяющий вредоносное условие.
- EXTRACTVALUE(7494, CONCAT(...)) — вызов уязвимой функции. Первый аргумент (7494) — произвольное число, оно не влияет на результат, но должно быть допустимым XML-фрагментом.
- CONCAT(0x7e, ..., 0x7e) — объединяет тильды (символ ~, код 0x7e) с полезной нагрузкой. Тильды нужны, чтобы MySQL гарантированно сгенерировал ошибку XPATH и вывел содержимое между ними.
- (SELECT (ELT(7494=7494,1))) — подзапрос, возвращающий результат выражения
ELT(7494=7494,1). ФункцияELT()возвращает N-й элемент из списка. Здесь условие7494=7494всегда истинно (1), поэтому ELT(1,1) вернёт строку '1'. В реальной атаке вместо этого подзапроса стоял бы, например,(SELECT table_name FROM information_schema.tables LIMIT 1). - -- - — комментарий, который «отрезает» оставшуюся часть оригинального SQL-запроса, чтобы не нарушать синтаксис.
Таким образом, хакер заставляет сервер выполнить подзапрос, а затем вывести его результат в тексте ошибки. Это позволяет обойти ограничения, когда приложение не показывает данные напрямую, но отображает сообщения об ошибках.
Почему EXTRACTVALUE опасна?
Функция EXTRACTVALUE() (как и UPDATEXML()) появилась в MySQL 5.1 и часто используется разработчиками для работы с XML. Проблема в том, что при передаче в неё пользовательских данных без экранирования она становится каналом утечки информации. Основные причины уязвимости:
- Отсутствие параметризованных запросов.
- Вывод ошибок СУБД прямо в браузер.
- Использование устаревших версий MySQL (до 8.0), где функция не удалена.
Стоит отметить, что в MySQL 8.0 функции EXTRACTVALUE() и UPDATEXML() были удалены, что снижает риск подобных атак на современных серверах. Однако многие проекты до сих пор работают на старых версиях.
Как защититься от error-based SQL-инъекций?
Чтобы обезопасить базу данных, следуйте этим рекомендациям:
- Используйте подготовленные выражения (prepared statements). Они разделяют код и данные, делая внедрение невозможным.
- Отключите вывод ошибок СУБД. Настройте логирование ошибок в файл, а пользователю показывайте общее сообщение.
- Обновите MySQL до версии 8.0+. Там опасные функции уже удалены.
- Применяйте принцип наименьших привилегий. Учётная запись веб-приложения не должна иметь прав на чтение системных таблиц.
- Используйте WAF (Web Application Firewall). Он может блокировать подозрительные конструкции вроде EXTRACTVALUE.
Также рекомендуется проводить регулярные аудиты кода и пентесты. Помните: даже одна неэкранированная кавычка может открыть злоумышленнику доступ ко всей базе.
Заключение
Запрос ))) AND EXTRACTVALUE(7494,CONCAT(0x7e,((SELECT (ELT(7494=7494,1)))),0x7e))-- - — это учебный пример эксплуатации error-based SQL-инъекции. Он демонстрирует, как через функцию EXTRACTVALUE можно заставить MySQL выдать данные в сообщении об ошибке. Понимание таких атак помогает разработчикам и администраторам лучше защищать свои системы. Всегда проверяйте входящие данные, используйте параметризацию и не оставляйте устаревшие версии СУБД.
Комментарии
—Войдите, чтобы оставить комментарий