Строка OR EXTRACTVALUE(8503,CONCAT(0x7e,((SELECT (ELT(8503=8503,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используют для извлечения данных из базы через намеренно вызванные ошибки, текст которых возвращается в ответе сервера. В этой статье мы подробно разберём, как работает данный запрос, какие функции задействованы и как защититься от подобных атак.
Что такое error-based SQL-инъекция
SQL-инъекция — это один из самых распространённых способов взлома веб-приложений, при котором злоумышленник внедряет свой SQL-код в запрос, выполняемый базой данных. Error-based инъекция — это частный случай, когда атакующий заставляет СУБД выдать сообщение об ошибке, содержащее полезные данные (например, версию базы, имена таблиц, логины и пароли пользователей).
В MySQL для этого часто используют функции EXTRACTVALUE и UPDATEXML. Они предназначены для работы с XML, но при некорректных аргументах возвращают ошибку, в тексте которой может оказаться результат подзапроса.
Разбор строки инъекции
Рассмотрим запрос по частям:
OR— логический оператор, который добавляется к оригинальному условию. Если исходный запрос былSELECT ... WHERE id = '$id', то после подстановки получаетсяWHERE id = '' OR EXTRACTVALUE(...). Это заставляет базу выполнить нашу функцию.EXTRACTVALUE(8503, CONCAT(0x7e, ((SELECT (ELT(8503=8503,1)))), 0x7e))— вызов функцииEXTRACTVALUEс двумя аргументами. Первый аргумент (8503) — произвольное число, второй — XML-строка, сформированная черезCONCAT.CONCAT(0x7e, ((SELECT (ELT(8503=8503,1)))), 0x7e)— объединяет символ~(0x7e), результат подзапроса и снова~. Символ~используется как маркер, чтобы в сообщении об ошибке было легко найти внедрённые данные.(SELECT (ELT(8503=8503,1)))— подзапрос, возвращающий значение.ELT(N, str1, str2, ...)возвращает строку с номером N. Здесь условие8503=8503всегда истинно, поэтомуELT(1,1)вернёт1. В реальной атаке вместо1подставляют подзапрос, извлекающий данные, например(SELECT password FROM users LIMIT 1).-- -— комментарий, который отсекает оставшуюся часть оригинального SQL-запроса, чтобы не возникло синтаксической ошибки.
Как это работает на практике
Когда MySQL выполняет EXTRACTVALUE(8503, '~1~'), функция пытается разобрать строку как XML. Поскольку ~1~ не является корректным XML-документом, СУБД генерирует ошибку вида:
XPATH syntax error: '~1~'
В этом сообщении содержится результат подзапроса. Атакующий, получая такие ошибки в ответе сервера, может посимвольно извлекать данные из базы. Например, подставляя вместо 1 подзапрос (SELECT table_name FROM information_schema.tables LIMIT 1), он получит имя первой таблицы в ошибке.
Зачем нужны 0x7e и ELT
0x7e — это шестнадцатеричное представление символа ~ (тильда). Он используется как разделитель, чтобы в сообщении об ошибке было легко отделить внедрённые данные от остального текста. ELT — функция, возвращающая N-ю строку из списка. В простейшем случае ELT(8503=8503,1) возвращает 1, так как условие истинно. Это демонстрационный пример; в реальной атаке вместо 1 может быть любой подзапрос.
Последствия успешной инъекции
Если злоумышленнику удаётся эксплуатировать такую уязвимость, он может:
- получить доступ к конфиденциальным данным (пароли, персональные данные пользователей, платёжная информация);
- изменить или удалить данные в базе;
- выполнить административные операции, если у учётной записи базы данных достаточно прав;
- получить полный контроль над сервером в некоторых конфигурациях.
Как защититься от error-based SQL-инъекций
Основной метод защиты — использование параметризованных запросов (prepared statements). Они гарантируют, что пользовательский ввод никогда не будет интерпретирован как SQL-код. Дополнительные меры:
- Экранирование специальных символов — если по каким-то причинам нельзя использовать prepared statements, применяйте функции экранирования, предоставляемые драйвером базы данных.
- Ограничение прав пользователя БД — учётная запись, от имени которой работает веб-приложение, должна иметь минимально необходимые привилегии.
- Отключение вывода ошибок в production — сообщения об ошибках не должны попадать в ответ клиенту. Логируйте их на сервере.
- Использование WAF — веб-приложения firewall могут блокировать известные шаблоны атак, но не заменяют исправление уязвимостей.
- Регулярное обновление СУБД и фреймворков — закрывайте известные уязвимости.
Пример безопасного кода
Вместо конкатенации строк используйте параметризацию. Например, на PHP с PDO:
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $userId]);
Такой подход полностью исключает возможность SQL-инъекции, включая error-based.
Частые вопросы
Почему используется именно EXTRACTVALUE?
Функция EXTRACTVALUE доступна в MySQL и при передаче некорректного XML генерирует ошибку с указанием проблемного фрагмента. Это удобно для атакующего, так как в ошибке отображается переданная строка.
Что означает 8503 в запросе?
Это произвольное число, первый аргумент функции. Оно не несёт смысловой нагрузки, кроме как быть допустимым аргументом.
Можно ли использовать эту технику на других СУБД?
PostgreSQL, MS SQL и Oracle имеют свои аналоги error-based инъекций, но синтаксис и функции отличаются.
Заключение
Строка OR EXTRACTVALUE(8503,CONCAT(0x7e,((SELECT (ELT(8503=8503,1)))),0x7e))-- - — это не случайный набор символов, а тщательно сконструированный эксплойт для извлечения данных из MySQL через сообщения об ошибках. Понимание таких атак помогает разработчикам писать безопасный код и защищать веб-приложения. Главное правило: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий