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