Что такое SQL-инъекция через EXTRACTVALUE?
SQL-инъекция — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запросы к базе данных. Одной из разновидностей является error-based SQL-инъекция, когда хакер заставляет сервер выдать сообщение об ошибке, содержащее конфиденциальные данные. Функция EXTRACTVALUE в MySQL — популярный инструмент для таких атак, поскольку она работает с XML и XPath, а при некорректном выражении XPath генерирует ошибку, в тексте которой может отображаться переданное значение.
Рассматриваемый запрос:
'))) AND EXTRACTVALUE(7343,CONCAT(0x7e,((SELECT (ELT(7343=7343,1)))),0x7e))-- -
Это классический пример полезной нагрузки (payload) для error-based SQL-инъекции. Давайте разберём его по частям.
Анатомия полезной нагрузки
Начнём с начала строки:
')))— закрывающие кавычка и скобки. Они используются для завершения оригинального SQL-запроса, в который внедряется код. Количество скобок зависит от структуры уязвимого запроса.AND— логический оператор, позволяющий присоединить дополнительное условие.EXTRACTVALUE(7343, CONCAT(...))— вызов функцииEXTRACTVALUE. Первый аргумент (7343) — произвольное число, второй — XPath-выражение, которое мы формируем динамически.CONCAT(0x7e, ((SELECT (ELT(7343=7343,1)))), 0x7e)— конкатенация символа~(0x7e), результата подзапроса и ещё одного~.-- -— комментарий, отсекающий оставшуюся часть оригинального запроса.
Функция EXTRACTVALUE
EXTRACTVALUE(XML_frag, XPath_expr) возвращает текст первого текстового узла, найденного по XPath-выражению. Если XPath-выражение синтаксически неверно, MySQL выдаёт ошибку вида XPATH syntax error: '...', где ... — часть переданного выражения. Это и есть канал утечки данных.
Подзапрос с ELT
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В нашем случае ELT(7343=7343, 1) — условие 7343=7343 всегда истинно, поэтому возвращается 1. Это простейший пример; на практике вместо 1 подставляется подзапрос, извлекающий нужные данные, например, имя пользователя или хэш пароля.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE id = '))) AND EXTRACTVALUE(7343,CONCAT(0x7e,((SELECT (ELT(7343=7343,1)))),0x7e))-- -';
После подстановки полезной нагрузки СУБД выполнит:
- Закроет исходные кавычки и скобки.
- Вычислит
CONCAT(0x7e, 1, 0x7e), получив строку~1~. - Передаст эту строку в
EXTRACTVALUEкак XPath-выражение. Поскольку~1~не является корректным XPath, возникнет ошибка:XPATH syntax error: '~1~'. - Текст ошибки вернётся в ответе сервера, и атакующий увидит значение
1.
Заменив 1 на подзапрос, например (SELECT user FROM mysql.user LIMIT 1), злоумышленник получит имя пользователя базы данных в сообщении об ошибке.
Какие данные можно извлечь?
С помощью этой техники атакующий может постепенно извлекать любую информацию из базы:
- имена таблиц и столбцов из
INFORMATION_SCHEMA; - учётные данные пользователей (логины, пароли, хэши);
- персональные данные клиентов;
- номера кредитных карт и другую финансовую информацию.
Ограничение — длина вывода в сообщении об ошибке (обычно 32 символа), поэтому данные извлекаются посимвольно с использованием функций SUBSTRING и LIMIT.
Пример из реальной практики
В отчётах по пентесту часто приводится похожий вектор: ' AND (SELECT 1 FROM (SELECT COUNT(*), CONCAT((SELECT CONCAT(0x7e, (SELECT user FROM data LIMIT 1,1), 0x7e)), FLOOR(RAND(0)*2))x FROM information_schema.tables GROUP BY x)a) AND '1'='1. Здесь используется GROUP BY с RAND() для вызова ошибки дублирования ключа, но цель та же — вытащить данные через сообщение об ошибке.
Как защититься от error-based SQL-инъекций
Основной метод защиты — использование параметризованных запросов (prepared statements). Они разделяют код и данные, поэтому внедрение SQL-кода становится невозможным. Дополнительные меры:
- Экранирование специальных символов (функция
mysqli_real_escape_string). - Валидация и фильтрация входных данных на стороне сервера.
- Отключение вывода подробных ошибок БД в production-среде.
- Использование ORM и современных фреймворков, которые автоматически применяют параметризацию.
- Регулярное обновление СУБД и применение WAF для блокировки подозрительных запросов.
Важно понимать, что EXTRACTVALUE — не единственная функция, эксплуатируемая в error-based атаках. Аналогично используются UPDATEXML, GTID_SUBSET и другие. Поэтому защита должна быть комплексной.
Заключение
Полезная нагрузка '))) AND EXTRACTVALUE(7343,CONCAT(0x7e,((SELECT (ELT(7343=7343,1)))),0x7e))-- - — это учебный пример эксплуатации error-based SQL-инъекции через функцию EXTRACTVALUE. Она демонстрирует, как злоумышленник может заставить СУБД выдать данные в сообщении об ошибке. Понимание таких векторов атак необходимо разработчикам и специалистам по безопасности для построения надёжной защиты веб-приложений.
Комментарии
—Войдите, чтобы оставить комментарий