Что такое SQL-инъекция через ExtractValue?
SQL-инъекция (SQL injection) — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Существует несколько типов таких атак: union-based, boolean-based, time-based и error-based. Последний тип, error-based, основан на извлечении данных через сообщения об ошибках, которые возвращает СУБД. Функция ExtractValue в MySQL часто используется именно для error-based инъекций.
В запросе пользователя: %'))) AND EXTRACTVALUE(4070,CONCAT(0x7e,((SELECT (ELT(4070=4070,1)))),0x7e))-- - — представлен классический пример error-based SQL-инъекции. Давайте разберём его по частям.
Структура payload
Payload состоит из нескольких частей:
%')))— закрывающие символы, которые пытаются завершить оригинальный SQL-запрос, чтобы внедрить свой код. Символ%— это URL-кодирование пробела, а'— закрывающая кавычка для строкового литерала. Скобки закрывают возможные открытые скобки в исходном запросе.AND EXTRACTVALUE(4070,CONCAT(0x7e,((SELECT (ELT(4070=4070,1)))),0x7e))— основная часть инъекции. ФункцияEXTRACTVALUE(XML_frag, XPath_expr)извлекает значение из XML-фрагмента по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой выводится переданное значение.-- -— комментарий, который обрезает оставшуюся часть оригинального запроса.
Функция EXTRACTVALUE
Синтаксис: EXTRACTVALUE(XML_frag, XPath_expr). Первый аргумент — строка, содержащая XML-документ. Второй — XPath-выражение. Если XPath содержит недопустимые символы (например, ~), MySQL возвращает ошибку вида: XPATH syntax error: '~...~'. Именно это и используется для вывода данных: злоумышленник конструирует XPath так, чтобы в сообщении об ошибке появилась нужная информация.
В нашем payload первый аргумент — 4070 (просто число, не XML), но это не важно, так как ошибка возникает на этапе разбора XPath. Второй аргумент — CONCAT(0x7e, ((SELECT (ELT(4070=4070,1)))), 0x7e). Здесь 0x7e — это шестнадцатеричное представление символа ~ (тильда). CONCAT объединяет тильду, результат подзапроса и ещё одну тильду. В итоге XPath-выражение начинается с ~, что недопустимо, и MySQL выдаёт ошибку, содержащую этот XPath, то есть нашу строку с данными.
Подзапрос с ELT
ELT(N, str1, str2, ...) — функция, возвращающая N-й элемент из списка строк. В нашем случае ELT(4070=4070, 1). Выражение 4070=4070 всегда истинно, то есть равно 1. Значит, ELT вернёт первый элемент — 1. Подзапрос (SELECT (ELT(4070=4070,1))) вернёт 1. Таким образом, CONCAT соберёт строку ~1~. При вызове EXTRACTVALUE с таким XPath MySQL выдаст ошибку: XPATH syntax error: '~1~'. Это простейший пример, демонстрирующий работу метода. В реальной атаке вместо 1 подставляются имена таблиц, колонок или другие данные, извлекаемые из базы.
Зачем это нужно злоумышленнику?
Error-based инъекции позволяют получать информацию из базы данных, даже если приложение не выводит результаты запроса напрямую. Сообщения об ошибках часто отображаются на странице или попадают в логи, которые могут быть доступны атакующему. С помощью EXTRACTVALUE можно извлечь:
- версию MySQL (
version()), - имя текущего пользователя (
user()), - имя базы данных (
database()), - имена таблиц и колонок из
information_schema, - непосредственно данные (логины, пароли, персональную информацию).
Пример извлечения версии: AND EXTRACTVALUE(1, CONCAT(0x7e, version(), 0x7e)) — в ошибке появится версия СУБД.
Ошибка 1105 и её роль
MySQL возвращает ошибку с кодом 1105 (ER_UNKNOWN_ERROR) для ошибок XPath. В сообщении будет текст: XPATH syntax error: '~...~'. Именно этот текст и содержит извлечённые данные. Если приложение выводит ошибки базы данных пользователю, злоумышленник может их прочитать. Если ошибки скрыты, атака может не сработать, но в некоторых случаях данные попадают в логи.
Как защититься от таких инъекций?
Основной метод защиты — использование параметризованных запросов (prepared statements). Это исключает возможность внедрения SQL-кода, так как данные передаются отдельно от структуры запроса. Дополнительные меры:
- Экранирование специальных символов (хотя это менее надёжно, чем параметризация).
- Ограничение прав пользователя базы данных: не давайте приложению прав на чтение
information_schemaбез необходимости. - Отключение вывода ошибок СУБД в продакшене: настройте
display_errors = Offи логирование ошибок в файл, недоступный извне. - Использование WAF (Web Application Firewall) для фильтрации подозрительных запросов.
- Регулярное обновление MySQL, так как в новых версиях некоторые функции могут быть удалены или изменены (например, в MySQL 8.0 функция EXTRACTVALUE устарела).
Заключение
Payload %'))) AND EXTRACTVALUE(4070,CONCAT(0x7e,((SELECT (ELT(4070=4070,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции через функцию EXTRACTVALUE. Он демонстрирует, как злоумышленник может заставить базу данных выдать ошибку, содержащую полезную информацию. Понимание таких атак помогает разработчикам и администраторам лучше защищать свои системы. Всегда используйте параметризованные запросы и следите за актуальностью программного обеспечения.
Комментарии
—Войдите, чтобы оставить комментарий