Что это за запрос?
Строка %' OR EXTRACTVALUE(1855,CONCAT(0x7e,((SELECT (ELT(1855=1855,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекция на основе ошибок) в СУБД MySQL. Подобные конструкции часто встречаются в отчётах пентестеров и в учебных материалах по безопасности веб-приложений. Запрос пытается внедрить в уязвимый параметр вредоносный SQL-код, который заставит сервер выдать сообщение об ошибке, содержащее полезные для атакующего данные.
Разбор по частям
Давайте разберём эту строку на составляющие, чтобы понять логику атаки.
1. %' — закрытие исходного запроса
Символ % часто используется в SQL-запросах как шаблон для поиска (например, в LIKE '%...%'). Закрывающая кавычка ' пытается завершить строковый литерал в исходном запросе, чтобы далее внедрить собственный код. Если приложение не фильтрует ввод, это позволяет «вырваться» из контекста и добавить произвольные SQL-выражения.
2. OR EXTRACTVALUE(...) — вызов уязвимой функции
EXTRACTVALUE(XML_document, XPath_expression) — это встроенная функция MySQL, предназначенная для извлечения значений из XML-документов с помощью XPath. Однако при некорректном XPath-выражении она генерирует ошибку, текст которой может содержать переданные данные. Это и используется для извлечения информации из базы.
В нашем случае первый аргумент — 1855 (произвольное число, может быть любым), второй — CONCAT(0x7e,((SELECT (ELT(1855=1855,1)))),0x7e).
3. CONCAT(0x7e, ..., 0x7e) — формирование строки с тильдами
0x7e — это шестнадцатеричное представление символа ~ (тильда). Он используется как маркер, чтобы в сообщении об ошибке легко было найти внедрённые данные. Конструкция CONCAT('~', ..., '~') оборачивает результат подзапроса в тильды.
4. SELECT (ELT(1855=1855,1)) — проверка условия
ELT(N, str1, str2, ...) — функция MySQL, возвращающая N-ю строку из списка. Если N=1, возвращается первая строка, если N=2 — вторая и т.д. Если N меньше 1 или больше числа аргументов, возвращается NULL.
Выражение 1855=1855 всегда истинно, поэтому в MySQL оно приводится к числу 1. Таким образом, ELT(1, 1) вернёт строку '1'. Это простейший пример; в реальных атаках вместо 1855=1855 может стоять подзапрос, извлекающий данные (например, имя таблицы, версию СУБД и т.п.).
5. -- - — комментарий
Двойной дефис с пробелом (или -- -) в MySQL означает начало комментария до конца строки. Это позволяет «отрезать» оставшуюся часть оригинального SQL-запроса, чтобы синтаксис был корректным.
Как это работает на практике
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE name LIKE '%ЗАПРОС%';
После подстановки нашей строки вместо ЗАПРОС получаем:
SELECT * FROM users WHERE name LIKE '%%' OR EXTRACTVALUE(1855,CONCAT(0x7e,((SELECT (ELT(1855=1855,1)))),0x7e))-- -%';
MySQL выполнит EXTRACTVALUE с некорректным XPath (второй аргумент не является допустимым XPath-выражением), что вызовет ошибку вида:
ERROR 1105 (HY000): XPATH syntax error: '~1~'
В сообщении об ошибке мы видим ~1~ — это результат подзапроса, обёрнутый тильдами. Злоумышленник может заменить ELT(1855=1855,1) на подзапрос, возвращающий, например, имя текущей базы данных, версию MySQL или хеши паролей. Ошибка выведет эти данные прямо в ответе сервера.
Зачем это нужно атакующему?
Error-based инъекции — мощный инструмент, когда приложение не выводит данные напрямую, но возвращает сообщения об ошибках СУБД. С помощью EXTRACTVALUE (или аналогичных функций, таких как UPDATEXML) можно посимвольно извлекать любую информацию из базы. Это один из классических методов, описанных в «SQL Injection Cheat Sheet».
Как защититься?
- Используйте параметризованные запросы (prepared statements). Это самый надёжный способ: данные никогда не интерпретируются как SQL-код.
- Экранируйте специальные символы. Если параметризация невозможна, применяйте функции экранирования, предоставляемые драйвером БД (например,
mysqli_real_escape_stringв PHP). - Отключите вывод ошибок СУБД на продакшене. Сообщения об ошибках должны логироваться, а не показываться пользователю.
- Ограничьте права пользователя БД. Веб-приложение должно работать с минимально необходимыми привилегиями.
- Используйте WAF. Веб-приложения-экраны могут блокировать подозрительные конструкции, но не полагайтесь только на них.
Вывод
Строка %' OR EXTRACTVALUE(1855,CONCAT(0x7e,((SELECT (ELT(1855=1855,1)))),0x7e))-- - — это учебный пример эксплуатации error-based SQL-инъекции в MySQL. Она демонстрирует, как с помощью встроенных функций можно заставить сервер выдать данные в сообщении об ошибке. Понимание таких векторов атак критически важно для разработчиков и специалистов по безопасности, чтобы своевременно закрывать уязвимости и защищать данные пользователей.
Комментарии
—Войдите, чтобы оставить комментарий