Что это за строка?
Запрос `)))) AND EXTRACTVALUE(8108,CONCAT(0x7e,((SELECT (ELT(8108=8108,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Подобные конструкции часто встречаются в логах веб-серверов, в отчётах систем обнаружения вторжений (IDS) и в базах уязвимостей. Их цель — заставить базу данных выдать конфиденциальную информацию прямо в тексте сообщения об ошибке, которое затем отобразится на странице сайта или вернётся в ответе API.
Строка начинается с последовательности закрывающих скобок и кавычек, чтобы «разорвать» оригинальный SQL-запрос приложения и внедрить собственный код. Далее идёт оператор AND, за которым следует вызов функции EXTRACTVALUE — она предназначена для работы с XML и в определённых условиях генерирует ошибку, содержащую переданные ей данные. Завершают конструкцию комментарий -- -, который «съедает» остаток исходного запроса, и специальные символы 0x7e (тильда ~), служащие маркерами для извлечения полезной нагрузки из текста ошибки.
Как работает error-based SQL-инъекция
Error-based — это метод эксплуатации SQL-инъекций, при котором злоумышленник намеренно вызывает ошибку базы данных, чтобы в её сообщении увидеть результат выполнения подзапроса. В отличие от blind-инъекций, где данные извлекаются по одному биту через логические условия или задержки, здесь ответ приходит сразу и в читаемом виде.
В MySQL для этих целей традиционно использовались функции EXTRACTVALUE() и UPDATEXML(). Обе они относятся к работе с XML: первая извлекает значение из XML-фрагмента, вторая обновляет его. Если передать в качестве первого аргумента корректный XML-документ, а в качестве второго — XPath-выражение, содержащее недопустимые символы, СУБД сгенерирует ошибку вида:
XPATH syntax error: '~1~'
Именно этот текст и является целью атакующего: подставив в XPath результат подзапроса, он получает его в сообщении об ошибке.
Разбор внедрённого кода по частям
- `)))) — последовательность символов для «обрыва» исходного запроса. Конкретный набор зависит от того, как выглядит уязвимый SQL-код приложения (наличие кавычек, скобок, операторов).
- AND — логический оператор, присоединяющий вредоносное условие к оригинальному запросу.
- EXTRACTVALUE(8108, ...) — вызов уязвимой функции. Первый аргумент (8108) — произвольное число, которое в данном случае не несёт смысловой нагрузки, но должно быть допустимым для синтаксиса.
- CONCAT(0x7e, ((SELECT (ELT(8108=8108,1)))), 0x7e) — конкатенация тильды, результата подзапроса и ещё одной тильды.
0x7e— шестнадцатеричное представление символа~, который используется как маркер начала и конца полезных данных в сообщении об ошибке. - SELECT (ELT(8108=8108,1)) — подзапрос, возвращающий значение.
ELT()выбирает N-й элемент из списка; здесь условие8108=8108всегда истинно, поэтому возвращается1. В реальной атаке на месте этой конструкции стоял бы запрос к системным таблицам, напримерSELECT version()илиSELECT table_name FROM information_schema.tables. - -- - — комментарий, отсекающий остаток оригинального запроса. Пробел после двух дефисов обязателен в MySQL.
Какие данные можно извлечь
Если приложение уязвимо и выводит ошибки СУБД пользователю, атакующий может получить практически любую информацию, доступную учётной записи, от имени которой работает веб-приложение:
- Версию СУБД (
SELECT version()). - Имя текущей базы данных и пользователя (
SELECT database(),SELECT user()). - Список таблиц и колонок через
information_schema. - Логины, пароли (в виде хешей), персональные данные пользователей.
- Содержимое любых других таблиц, к которым есть доступ.
На практике злоумышленники часто автоматизируют процесс с помощью инструментов вроде sqlmap, которые сами подбирают синтаксис инъекции под конкретную СУБД и извлекают данные посимвольно или целыми строками.
Почему EXTRACTVALUE перестала быть надёжным инструментом
Начиная с MySQL 5.7.9 функция EXTRACTVALUE() была объявлена устаревшей (deprecated), а в MySQL 8.0 — удалена. То же самое произошло с UPDATEXML(). Это связано с тем, что поддержка XML в ядре СУБД была пересмотрена, а сами функции часто использовались именно для эксплуатации уязвимостей. Однако это не означает, что error-based инъекции исчезли: в современных версиях MySQL для вызова ошибок с полезной нагрузкой применяются другие приёмы, например функция GTID_SUBSET() или конструкции с JSON_KEYS() и NAME_CONST().
Кроме того, многие веб-приложения сегодня настроены так, чтобы не показывать пользователю подробные сообщения об ошибках базы данных. Это существенно затрудняет error-based атаки, но не делает их невозможными — иногда ошибки всё же «просачиваются» через отладочные страницы, логи или ответы API.
Как защититься от подобных атак
Главный принцип защиты от SQL-инъекций любого типа — не доверять пользовательскому вводу и никогда не подставлять его в SQL-запрос напрямую. Рассмотрим ключевые меры:
- Параметризованные запросы (prepared statements). Это самый надёжный способ. Значения передаются отдельно от текста запроса, и СУБД не интерпретирует их как SQL-код. Такой подход поддерживают все современные драйверы и ORM.
- Хранимые процедуры с параметрами. Если они написаны корректно и не используют динамический SQL, риск инъекции снижается.
- Экранирование спецсимволов. Менее надёжно, чем параметризация, но может применяться как дополнительный барьер. Важно использовать функции экранирования, соответствующие конкретной СУБД.
- Ограничение прав учётной записи БД. Веб-приложение не должно подключаться к базе как root или пользователь с правами на чтение системных таблиц. Принцип наименьших привилегий существенно сокращает ущерб от успешной инъекции.
- Отключение вывода ошибок СУБД пользователю. Подробные сообщения должны писаться в лог, а посетитель видеть нейтральную страницу ошибки.
- Регулярное обновление СУБД и библиотек. Устаревшие версии MySQL содержат известные уязвимости, которые уже исправлены в новых релизах.
- Использование WAF. Специализированные межсетевые экраны для веб-приложений могут блокировать характерные шаблоны инъекций, включая конструкции с
EXTRACTVALUE.
Что делать, если вы нашли такую строку в логах
Если вы администратор сайта или безопасник и обнаружили в логах запрос, подобный приведённому, это сигнал о попытке взлома. Действия должны быть следующими:
- Зафиксируйте IP-адрес, время и полный текст запроса.
- Проверьте, не увенчалась ли попытка успехом: просмотрите ответы сервера, убедитесь, что в них нет сообщений об ошибках СУБД.
- Проведите аудит кода на предмет наличия уязвимых мест: поищите конкатенацию строк в SQL-запросах, динамическое построение запросов.
- При необходимости привлеките специалистов по информационной безопасности для пентеста.
- Настройте оповещения о подобных событиях, чтобы реагировать оперативно.
Помните: даже если конкретная попытка не удалась, злоумышленник может вернуться с другим вектором атаки. Безопасность базы данных — это непрерывный процесс, а не разовое мероприятие.
Краткий итог
Строка `)))) AND EXTRACTVALUE(8108,CONCAT(0x7e,((SELECT (ELT(8108=8108,1)))),0x7e))-- - — это учебный или реальный пример error-based SQL-инъекции для MySQL. Она демонстрирует, как через вызов уязвимой функции и провоцирование ошибки можно извлечь данные из базы. Хотя в новых версиях MySQL функция EXTRACTVALUE удалена, сама техника error-based инъекций никуда не исчезла. Единственная надёжная защита — параметризованные запросы, ограничение прав и внимательный мониторинг логов.
Комментарии
—Войдите, чтобы оставить комментарий