Что это за строка?
Строка %") AND EXTRACTVALUE(2947,CONCAT(0x7e,((SELECT (ELT(2947=2947,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто встречаются в логах веб-серверов, в полях ввода форм и в параметрах URL, когда злоумышленник пытается протестировать сайт на уязвимость.
В отличие от UNION-инъекций, где данные выводятся напрямую в ответе сервера, error-based метод заставляет базу данных сгенерировать ошибку, содержащую нужную информацию. Это особенно полезно, когда приложение не отображает результаты запроса, но выводит сообщения об ошибках.
Разбор компонентов инъекции
Давайте детально разберём каждый элемент этого запроса.
1. Начальный символ %")
Эта часть закрывает предыдущий SQL-запрос, который был сформирован приложением. Символ % часто используется в LIKE-запросах, а ") закрывает кавычку и скобку, завершая оригинальное выражение. Это позволяет внедрить собственный код.
2. Оператор AND
Логический оператор AND присоединяет вредоносное условие к исходному запросу. Если исходный запрос был истинным, то и всё выражение останется истинным, что позволит инъекции выполниться.
3. Функция EXTRACTVALUE(2947, ...)
EXTRACTVALUE — это встроенная функция MySQL для работы с XML. Она извлекает значение из XML-фрагмента по заданному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_фрагмент, XPath_выражение). В нашем случае первым аргументом является число 2947, которое не является корректным XML. Это приводит к ошибке, но перед этим MySQL пытается вычислить второй аргумент — XPath-выражение.
4. Функция CONCAT(0x7e, ..., 0x7e)
CONCAT объединяет строки. Здесь 0x7e — это шестнадцатеричное представление символа тильды (~). Тильды используются как маркеры, чтобы облегчить поиск нужных данных в сообщении об ошибке. Внутри CONCAT находится подзапрос.
5. Подзапрос (SELECT (ELT(2947=2947,1)))
ELT — функция, возвращающая N-й элемент из списка. В данном случае ELT(2947=2947, 1) вернёт 1, потому что условие 2947=2947 истинно (равно 1). Это простейшая проверка, которая всегда возвращает 1. В реальной атаке вместо 1 мог бы быть, например, database() или user(), чтобы извлечь имя базы данных или пользователя.
6. Комментарий -- -
Двойной дефис с пробелом (или -- -) — это комментарий в SQL. Он отсекает оставшуюся часть оригинального запроса, чтобы синтаксис был корректным.
Как работает атака
Когда MySQL выполняет функцию EXTRACTVALUE с некорректным XML, она генерирует ошибку вида: XPATH syntax error: '~1~'. Именно в этой ошибке и появляется результат подзапроса, обёрнутый в тильды. Злоумышленник может прочитать это сообщение, если приложение выводит ошибки базы данных на страницу.
В более сложных вариантах вместо ELT(2947=2947,1) подставляются функции вроде CONCAT(version(), user(), database()), что позволяет получить конфиденциальную информацию. Также часто используется EXTRACTVALUE(1, CONCAT(0x7e, (SELECT ...), 0x7e)).
Цели злоумышленника
- Получение версии СУБД — помогает подобрать дальнейшие эксплойты.
- Извлечение имён таблиц и колонок — для последующей кражи данных.
- Чтение учётных данных — логинов, паролей, хешей.
- Обход аутентификации — внедрение условий, делающих запрос истинным.
Защита от error-based SQL-инъекций
Чтобы предотвратить такие атаки, необходимо применять комплекс мер:
- Использовать подготовленные выражения (prepared statements) с параметризацией. Это самый надёжный способ, так как данные не смешиваются с кодом.
- Экранировать специальные символы — например, с помощью
mysqli_real_escape_stringв PHP. - Отключить вывод ошибок БД на продакшене. Ошибки должны логироваться, а не показываться пользователю.
- Применять WAF (Web Application Firewall), который может блокировать подозрительные запросы.
- Регулярно обновлять СУБД и фреймворки, чтобы закрыть известные уязвимости.
Пример безопасного кода на PHP
Вместо конкатенации строк используйте PDO с подготовленными выражениями:
$stmt = $pdo->prepare('SELECT * FROM users WHERE name = :name');
$stmt->execute(['name' => $userInput]);
Такой подход гарантирует, что пользовательский ввод не сможет изменить структуру SQL-запроса.
Заключение
Строка %") AND EXTRACTVALUE(2947,CONCAT(0x7e,((SELECT (ELT(2947=2947,1)))),0x7e))-- - — это не просто набор символов, а чётко спланированная попытка эксплуатации уязвимости. Понимание механизмов таких атак помогает разработчикам и администраторам лучше защищать свои системы. Если вы нашли подобный код в логах, это сигнал о необходимости проверить безопасность вашего веб-приложения.
Комментарии
—Войдите, чтобы оставить комментарий