Введение
Строка ' OR EXTRACTVALUE(8370,CONCAT(0x7e,((SELECT (ELT(8370=8370,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции для СУБД MySQL. Такие пейлоады используются злоумышленниками для извлечения данных из базы через вывод сообщений об ошибках. В этой статье мы детально разберём, как работает данный запрос, какие функции задействованы и как защититься от подобных атак.
Что такое error-based SQL-инъекция
SQL-инъекция — это один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет вредоносный SQL-код в запрос к базе данных. Error-based инъекция — это разновидность, при которой атакующий заставляет сервер вернуть сообщение об ошибке, содержащее полезные данные (например, имена таблиц, логины, пароли). Это возможно, если приложение выводит ошибки БД пользователю.
Основная идея: с помощью специальных функций (таких как EXTRACTVALUE, UPDATEXML) вызывается ошибка, в текст которой подставляется результат подзапроса. Таким образом, злоумышленник может «читать» данные из базы, не имея прямого доступа к ней.
Разбор пейлоада по частям
Рассмотрим каждый элемент запроса:
- ' — одинарная кавычка, закрывающая строковый литерал в уязвимом запросе. Это позволяет выйти за пределы исходного значения и добавить собственный SQL-код.
- OR — логический оператор, который делает условие всегда истинным (если хотя бы одна часть верна). В данном случае используется для того, чтобы запрос выполнился, даже если исходное условие ложно.
- EXTRACTVALUE(8370, CONCAT(...)) — функция MySQL, извлекающая значение из XML-документа. Первый аргумент — XML-строка (здесь число 8370, которое будет преобразовано в строку), второй — XPath-выражение. Если XPath-выражение некорректно, генерируется ошибка, содержащая это выражение.
- CONCAT(0x7e, ((SELECT (ELT(8370=8370,1)))), 0x7e) — конкатенация трёх частей: символа тильды (
0x7eв шестнадцатеричном виде), результата подзапроса и ещё одной тильды. Тильда используется как разделитель, чтобы облегчить извлечение данных из сообщения об ошибке. - SELECT (ELT(8370=8370,1)) — подзапрос, возвращающий результат функции
ELT.ELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь8370=8370— всегда истинное условие (1), поэтомуELT(1, 1)вернёт строку '1'. В реальной атаке вместо этого подзапроса мог бы быть, например,SELECT password FROM users LIMIT 1. - -- - — комментарий, который обрезает оставшуюся часть исходного запроса. Пробел после
--обязателен в MySQL, а дефис добавлен для надёжности.
В результате выполнения такого запроса MySQL попытается вычислить EXTRACTVALUE с некорректным XPath (содержащим символы тильды), что вызовет ошибку вида: XPATH syntax error: '~1~'. В сообщении об ошибке отобразится результат подзапроса (в примере — '1').
Зачем нужен ELT и условие 8370=8370
Функция ELT используется для управления логикой: если условие истинно, возвращается первый элемент списка, иначе — NULL. В простейшем случае 8370=8370 всегда истинно, поэтому возвращается '1'. Это демонстрационный пейлоад, который показывает работоспособность инъекции. В реальной атаке злоумышленник заменил бы этот подзапрос на извлечение конкретных данных, например:
EXTRACTVALUE(8370,CONCAT(0x7e,(SELECT username FROM users LIMIT 1),0x7e))
Также часто используется ELT с условием, чтобы реализовать слепую инъекцию или извлечение посимвольно.
Как эксплуатируется уязвимость
Для успешной атаки необходимо, чтобы приложение передавало пользовательский ввод в SQL-запрос без должной обработки и выводило ошибки базы данных. Типичный сценарий:
- Злоумышленник находит параметр, который попадает в SQL-запрос (например,
?id=1). - Подставляет пейлоад вместо ожидаемого значения.
- Сервер выполняет запрос, возникает ошибка, и её текст возвращается в ответе.
- Атакующий анализирует сообщение и постепенно извлекает данные (имена таблиц, столбцов, содержимое).
Важно отметить, что error-based инъекции работают только при включённом выводе ошибок. В production-окружениях ошибки БД часто скрываются, что затрудняет атаку, но не делает её невозможной (существуют другие техники, например, blind SQLi).
Меры защиты
Чтобы предотвратить подобные атаки, необходимо:
- Использовать подготовленные выражения (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не смешиваются с кодом.
- Экранировать специальные символы при невозможности использования подготовленных выражений (например, функция
mysqli_real_escape_stringв PHP). - Отключать вывод ошибок БД в production-среде. Сообщения об ошибках должны логироваться, но не отображаться пользователю.
- Применять принцип наименьших привилегий для учётной записи БД, используемой веб-приложением.
- Регулярно обновлять СУБД и фреймворки, чтобы закрывать известные уязвимости.
- Использовать WAF (Web Application Firewall) для фильтрации подозрительных запросов.
Также рекомендуется проводить аудит кода и пентесты для выявления уязвимостей до того, как их обнаружат злоумышленники.
Заключение
Пейлоад ' OR EXTRACTVALUE(8370,CONCAT(0x7e,((SELECT (ELT(8370=8370,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции, демонстрирующий использование функций EXTRACTVALUE, CONCAT и ELT для извлечения данных через сообщения об ошибках. Понимание механизма таких атак помогает разработчикам и специалистам по безопасности создавать более защищённые приложения. Никогда не пренебрегайте проверкой входных данных и используйте современные методы защиты.
Комментарии
—Войдите, чтобы оставить комментарий