Что это за строка?
Строка )))) AND EXTRACTVALUE(8890,CONCAT(0x7e,((SELECT (ELT(8890=8890,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто используются злоумышленниками при тестировании на проникновение и в атаках на веб-приложения, где входные данные не фильтруются должным образом.
В основе лежит функция EXTRACTVALUE(), которая извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, содержащую переданный фрагмент. Это позволяет атакующему «вытащить» результат подзапроса в тексте ошибки.
Разбор структуры инъекции
Рассмотрим каждый элемент по отдельности:
))))— последовательность закрывающих скобок, которая «ломает» исходный SQL-запрос, заставляя его завершиться раньше и добавить условиеAND. Это нужно, чтобы внедрить свой код в существующий запрос.AND EXTRACTVALUE(8890,CONCAT(0x7e,((SELECT (ELT(8890=8890,1)))),0x7e))— основная полезная нагрузка. ФункцияEXTRACTVALUEпринимает два аргумента: XML-документ (здесь просто число 8890) и XPath-выражение. Второй аргумент формируется черезCONCAT, который объединяет тильду (0x7e), результат подзапроса и ещё одну тильду.-- -— комментарий, который отсекает оставшуюся часть оригинального запроса, чтобы избежать синтаксических ошибок.
Подзапрос (SELECT (ELT(8890=8890,1))) использует функцию ELT(). ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 8890=8890 — это логическое выражение, которое всегда истинно (1). Таким образом, ELT(1,1) вернёт строку '1'. Это простейший пример, демонстрирующий, что в реальной атаке вместо '1' мог бы быть, например, database(), user() или version().
Итоговое XPath-выражение будет содержать символ ~ и результат подзапроса, например ~1~. Поскольку это не является корректным XPath, MySQL выдаст ошибку вида: XPATH syntax error: '~1~'. В этом сообщении и окажутся данные, полученные из базы.
Зачем используется EXTRACTVALUE?
Функция EXTRACTVALUE появилась в MySQL 5.1 и предназначена для работы с XML. Однако из-за особенностей обработки ошибок она стала популярным инструментом для error-based SQL-инъекций. Аналогичными свойствами обладают функции UPDATEXML() и GTID_SUBSET().
Главное преимущество такого подхода — возможность получать данные напрямую в ответе сервера, без необходимости использовать слепые инъекции (blind SQL injection), которые требуют множества запросов и времени. Это делает атаку быстрой и эффективной.
Как работает error-based SQL-инъекция
Error-based SQL-инъекция эксплуатирует недостаточную обработку ошибок в веб-приложении. Когда приложение выводит сообщения об ошибках СУБД прямо на страницу, атакующий может внедрить код, который вызовет ошибку с полезной информацией. В случае с EXTRACTVALUE злоумышленник формирует XPath-выражение, включающее результат подзапроса, и сервер возвращает его в тексте ошибки.
Типичный сценарий атаки:
- Находится параметр, уязвимый для SQL-инъекции (например,
idв URL). - В параметр внедряется строка, подобная рассматриваемой.
- Приложение выполняет запрос и выводит ошибку MySQL, содержащую результат подзапроса.
- Атакующий последовательно извлекает имена таблиц, колонок и данные.
В примере с ELT(8890=8890,1) возвращается просто '1', но заменив '1' на database(), можно получить имя текущей базы данных. Далее, используя LIMIT и OFFSET, можно перебрать все таблицы и записи.
Примеры реальных атак
В 2019 году исследователь безопасности опубликовал разбор error-based SQL-инъекции через XPATH-инъекцию, обнаруженную при пентесте. В его примере использовалась похожая конструкция для извлечения имён колонок из information_schema.columns. Атака позволяла получить доступ к учётным данным пользователей.
Другой пример из практики: для извлечения имени пользователя применялся запрос:
' 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'='2
Здесь используется группировка с GROUP BY и функцией RAND() для вызова ошибки дублирования ключа, что также относится к error-based инъекциям.
Как защититься от SQL-инъекций
Основной метод защиты — использование параметризованных запросов (prepared statements). Они разделяют код SQL и данные, поэтому внедрённые строки не интерпретируются как часть запроса.
Дополнительные меры:
- Экранирование специальных символов с помощью функций вроде
mysqli_real_escape_string(для MySQL). - Валидация и фильтрация входных данных на стороне сервера.
- Ограничение привилегий пользователя базы данных, от имени которого работает приложение.
- Отключение вывода подробных ошибок СУБД в production-окружении.
- Использование WAF (Web Application Firewall) для блокировки подозрительных запросов.
- Регулярное обновление СУБД и фреймворков.
Важно понимать, что EXTRACTVALUE — не единственная функция, эксплуатируемая в error-based атаках. Злоумышленники могут использовать UPDATEXML, GTID_SUBSET, JSON_KEYS и другие. Поэтому защита должна быть комплексной.
Заключение
Строка )))) AND EXTRACTVALUE(8890,CONCAT(0x7e,((SELECT (ELT(8890=8890,1)))),0x7e))-- - — это яркий пример error-based SQL-инъекции, использующей функцию EXTRACTVALUE для извлечения данных через сообщения об ошибках MySQL. Понимание механизма таких атак помогает разработчикам и специалистам по безопасности своевременно выявлять и устранять уязвимости. Помните: лучшая защита — это параметризованные запросы и внимательное отношение к обработке пользовательского ввода.
Комментарии
—Войдите, чтобы оставить комментарий