Введение
Строка ')) AND EXTRACTVALUE(7001,CONCAT(0x7e,((SELECT (ELT(7001=7001,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используются злоумышленниками для извлечения данных из базы через сообщения об ошибках, которые возвращает сервер. В этой статье мы детально разберём, как работает этот запрос, какие функции задействованы и как защититься от подобных атак.
Что такое error-based SQL-инъекция?
SQL-инъекция — это один из самых распространённых способов взлома веб-приложений. Злоумышленник внедряет свой SQL-код в запрос, который выполняет сервер базы данных. При error-based инъекции атакующий заставляет СУБД выдать сообщение об ошибке, содержащее полезные данные (например, версию MySQL, имя базы, логин пользователя).
В MySQL для этого часто используют функции EXTRACTVALUE() и UPDATEXML(). Они предназначены для работы с XML, но при некорректных аргументах возвращают ошибку, в текст которой можно «вклеить» результат подзапроса.
Разбор запроса по частям
Рассмотрим наш запрос детально:
')) AND EXTRACTVALUE(7001,CONCAT(0x7e,((SELECT (ELT(7001=7001,1)))),0x7e))-- -
- ')) — закрывает ранее открытые скобки и кавычки в уязвимом параметре. Это позволяет внедрить собственный SQL-код.
- AND — логический оператор, который добавляет условие к исходному запросу.
- EXTRACTVALUE(7001, ...) — функция MySQL для извлечения значения из XML-строки. Первый аргумент — XML-документ (здесь просто число 7001, что уже некорректно), второй — XPath-выражение.
- CONCAT(0x7e, ((SELECT (ELT(7001=7001,1)))), 0x7e) — конкатенация тильды (0x7e — это символ ~), результата подзапроса и ещё одной тильды. Тильды служат маркерами, чтобы потом легко найти данные в сообщении об ошибке.
- SELECT (ELT(7001=7001,1)) — подзапрос, который возвращает 1, если 7001=7001 (всегда истина). Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь список состоит из одного элемента 1, поэтому возвращается 1. Это простейший пример; на практике вместо 1 подставляют подзапрос, извлекающий нужные данные (например, имя базы).
- -- - — комментарий, который отсекает оставшуюся часть оригинального SQL-запроса.
В результате MySQL пытается выполнить EXTRACTVALUE с некорректным XPath (потому что CONCAT возвращает строку, не являющуюся валидным XPath), и выдаёт ошибку вида: XPATH syntax error: '~1~'. В этом сообщении и оказываются данные, которые злоумышленник пытается извлечь.
Зачем нужны ELT и CONCAT?
Функция ELT() часто используется в error-based инъекциях для извлечения конкретных значений. Например, чтобы получить имя текущей базы данных, можно подставить:
ELT(1, database())
Тогда CONCAT сформирует строку ~имя_базы~, и она появится в ошибке. В нашем примере ELT(7001=7001,1) — это упрощённый тестовый вариант, который просто возвращает 1. Он используется для проверки уязвимости: если ошибка появляется, значит, инъекция возможна.
CONCAT собирает все части в одну строку. Символ 0x7e (тильда) выбран потому, что он редко встречается в обычных данных и легко заметен в сообщении об ошибке.
Как эксплуатируют такие инъекции?
После подтверждения уязвимости злоумышленник может извлекать любые данные: версию MySQL, имена таблиц и колонок, логины и пароли пользователей. Например, для получения версии СУБД используют:
AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))
Для перебора данных применяют LIMIT и OFFSET. Так, чтобы получить имя второй таблицы, меняют limit 0,1 на 1,1 и так далее.
Важно понимать: error-based инъекции работают только тогда, когда веб-приложение выводит сообщения об ошибках базы данных пользователю. Если ошибки скрыты, злоумышленник может использовать blind-инъекции (например, через time-based или boolean-based техники).
Как защититься от error-based SQL-инъекций?
Основные меры защиты:
- Использование подготовленных выражений (prepared statements). Это самый надёжный способ: параметры запроса передаются отдельно от SQL-кода, и внедрение становится невозможным.
- Экранирование специальных символов. Если prepared statements недоступны, необходимо экранировать все пользовательские данные перед подстановкой в запрос.
- Отключение вывода ошибок БД. Сообщения об ошибках не должны показываться пользователю — их следует логировать, а клиенту выдавать обобщённый ответ.
- Регулярное обновление СУБД и фреймворков. Устаревшие версии могут содержать дополнительные уязвимости.
- Использование WAF (Web Application Firewall). Современные WAF умеют распознавать типовые сигнатуры SQL-инъекций, включая EXTRACTVALUE.
Также рекомендуется проводить аудит кода и тестирование на проникновение, чтобы выявлять уязвимости до того, как ими воспользуются злоумышленники.
Заключение
Запрос ')) AND EXTRACTVALUE(7001,CONCAT(0x7e,((SELECT (ELT(7001=7001,1)))),0x7e))-- - — это не просто случайный набор символов, а тщательно сконструированная полезная нагрузка для проверки и эксплуатации error-based SQL-инъекции в MySQL. Понимание принципов её работы помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Помните: безопасность — это процесс, а не разовое действие.
Комментарии
—Войдите, чтобы оставить комментарий