Что это за строка и откуда она берётся?
Строка ))) AND EXTRACTVALUE(4015,CONCAT(0x7e,((SELECT (ELT(4015=4015,1)))),0x7e))-- - — это классический пример SQL-инъекции (SQL injection), а именно её разновидности error-based SQL injection. Подобные строки часто появляются в логах веб-серверов, в полях ввода форм или в параметрах URL, когда злоумышленник пытается атаковать сайт, работающий с базой данных MySQL. Цель такой инъекции — заставить сервер выполнить вредоносный SQL-запрос и вернуть информацию об ошибке, которая содержит полезные для атакующего данные.
Внешне строка выглядит как случайный набор символов, но на самом деле она тщательно сконструирована. Давайте разберём её по частям.
Анатомия инъекции
Начнём с конца: -- - — это комментарий в SQL. Всё, что идёт после него, игнорируется базой данных. Это нужно, чтобы обрезать оригинальный запрос, который мог бы помешать выполнению внедрённого кода. Символы ))) в начале — это закрывающие скобки, которые завершают ранее открытые скобки в уязвимом запросе. Злоумышленник предполагает, что исходный запрос содержит незакрытые скобки, и добавляет свои, чтобы синтаксис остался корректным.
Далее идёт AND EXTRACTVALUE(4015,CONCAT(0x7e,((SELECT (ELT(4015=4015,1)))),0x7e)). Здесь используется функция MySQL EXTRACTVALUE(), которая извлекает значение из XML-строки. Она принимает два аргумента: XML-документ и XPath-выражение. Если XPath-выражение синтаксически неверно, MySQL генерирует ошибку, в тексте которой отображается переданное значение. Это и есть основа error-based инъекции.
Как работает EXTRACTVALUE
Функция EXTRACTVALUE(XML, XPath) возвращает содержимое узла, указанного в XPath. Если XPath содержит недопустимые символы (например, тильду ~), MySQL выдаёт ошибку вида: XPATH syntax error: '~...~'. Внутри этих тильд оказывается результат подзапроса, который злоумышленник хочет получить. В нашем случае это CONCAT(0x7e, ((SELECT (ELT(4015=4015,1)))), 0x7e).
0x7e — это шестнадцатеричное представление символа ~ (тильда). CONCAT объединяет тильду, результат подзапроса и ещё одну тильду. Подзапрос SELECT (ELT(4015=4015,1)) использует функцию ELT(), которая возвращает N-й элемент из списка. Здесь 4015=4015 — всегда истина (1), поэтому ELT(1,1) вернёт 1. Это простейший тест: если инъекция сработает, в ошибке появится ~1~. На практике вместо 1 подставляют вызовы других функций, например VERSION(), DATABASE(), USER() или подзапросы, извлекающие логины и пароли из таблиц.
Зачем нужны цифры 4015?
Число 4015 в EXTRACTVALUE(4015, ...) — это просто произвольный идентификатор. Оно не несёт смысловой нагрузки, кроме того, что первый аргумент должен быть строкой (XML). MySQL автоматически преобразует число в строку. Аналогично 4015=4015 — это всегда истинное условие, которое можно заменить на любое другое, например 1=1. Такие числа часто используются для обхода простых фильтров, которые могут блокировать стандартные 1=1.
Пошаговый разбор строки
- ))) — закрываем скобки, оставшиеся от оригинального запроса.
- AND — логический оператор, присоединяющий наше условие к WHERE.
- EXTRACTVALUE(4015, ...) — вызов уязвимой функции.
- CONCAT(0x7e, ((SELECT (ELT(4015=4015,1)))), 0x7e) — формируем строку, которая будет показана в ошибке. Вместо
1может быть внедрён подзапрос для кражи данных. - -- - — комментарий, отсекающий остаток запроса.
Если сайт уязвим, в ответе сервера появится ошибка MySQL с текстом, содержащим результат подзапроса. Например: XPATH syntax error: '~1~'. Это подтверждает, что инъекция возможна, и позволяет атакующему перейти к извлечению данных.
Какие данные можно украсть?
С помощью error-based инъекций через EXTRACTVALUE злоумышленник может получить:
- версию MySQL (
VERSION()); - имя текущей базы данных (
DATABASE()); - имя пользователя, от которого работает скрипт (
USER()); - список таблиц и колонок из
information_schema; - логины, пароли, хеши, email и другие конфиденциальные данные из пользовательских таблиц.
Для этого в подзапрос вместо 1 подставляются конструкции вида (SELECT password FROM users LIMIT 0,1). Поскольку в ошибке отображается только ограниченное количество символов (обычно до 32), данные извлекаются посимвольно с помощью функций SUBSTRING и LIMIT.
Как защититься от таких атак?
Основная причина успеха подобных инъекций — недостаточная фильтрация пользовательского ввода и использование устаревших функций. Вот ключевые меры защиты:
- Используйте подготовленные выражения (prepared statements). Это самый надёжный способ: параметры запроса передаются отдельно от SQL-кода и не могут изменить его структуру.
- Применяйте ORM или библиотеки для работы с БД, которые автоматически экранируют опасные символы.
- Отключите вывод ошибок MySQL на продакшене. Ошибки должны логироваться, но не показываться пользователю.
- Обновите MySQL до версии 5.7.9 и выше. В новых версиях функция
EXTRACTVALUEпомечена как устаревшая, а в MySQL 8.0 удалена. Однако это не панацея — существуют другие функции для error-based инъекций, напримерUPDATEXML. - Проводите регулярный аудит кода и сканирование уязвимостей. Используйте инструменты SAST/DAST.
- Ограничьте права пользователя БД. Веб-приложение должно работать от имени пользователя с минимально необходимыми привилегиями (только SELECT, INSERT, UPDATE, DELETE для нужных таблиц).
Важно: даже если вы используете MySQL 8.0, гдеEXTRACTVALUEудалена, злоумышленники могут применить другие функции, напримерGTID_SUBSET,JSON_KEYSи т.п. Поэтому главная защита — это параметризованные запросы и валидация ввода.
Что делать, если вы нашли такую строку в логах?
Если вы обнаружили подобную строку в логах сервера, это признак того, что ваш сайт пытались взломать. Не паникуйте, но примите меры:
- Проверьте, не была ли инъекция успешной. Ищите в логах ошибки MySQL с тильдами или другими аномальными символами.
- Проанализируйте код на наличие уязвимых мест: все ли запросы используют подготовленные выражения?
- Если есть подозрение на утечку, смените пароли пользователей и ключи API.
- Настройте WAF (Web Application Firewall) для блокировки подозрительных запросов.
- Обратитесь к специалистам по информационной безопасности для аудита.
Заключение
Строка ))) AND EXTRACTVALUE(4015,CONCAT(0x7e,((SELECT (ELT(4015=4015,1)))),0x7e))-- - — это не случайный набор символов, а рабочий эксплойт для проверки уязвимости SQL-инъекции. Он использует функцию EXTRACTVALUE для вызова ошибки, в тексте которой передаётся результат подзапроса. Понимание механики таких атак помогает разработчикам и администраторам лучше защищать свои системы. Помните: лучшая защита — это использование подготовленных выражений и своевременное обновление программного обеспечения.
Комментарии
—Войдите, чтобы оставить комментарий