Что это за строка?
Строка ' OR EXTRACTVALUE(2746,CONCAT(0x7e,((SELECT (ELT(2746=2746,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто встречаются в отчётах по пентесту и в логах веб-серверов, когда злоумышленник пытается проверить уязвимость параметра на SQL-инъекцию.
Как работает эта инъекция?
Разберём по частям:
' OR ...— закрывает кавычку в уязвимом SQL-запросе и добавляет условие OR, чтобы запрос выполнился даже если исходное условие ложно.EXTRACTVALUE(2746, CONCAT(0x7e, ..., 0x7e))— функция MySQL для работы с XML. Она извлекает значение из XML-документа по XPath-выражению. Если XPath-выражение некорректно, MySQL выдаёт ошибку, в тексте которой отображается переданный аргумент.CONCAT(0x7e, ..., 0x7e)— объединяет символы тильды (~, код 0x7e) с результатом подзапроса. Тильда используется как маркер, чтобы потом легко найти данные в сообщении об ошибке.(SELECT (ELT(2746=2746,1)))— подзапрос, который возвращает 1, если 2746=2746 (всегда истина). ELT — функция, возвращающая N-й элемент из списка. Здесь она возвращает 1. В реальной атаке вместо этого подзапроса внедряют запрос к системным таблицам, например,SELECT table_name FROM information_schema.tables.-- -— комментарий, который отсекает оставшуюся часть оригинального SQL-запроса.
В результате MySQL пытается выполнить EXTRACTVALUE с XPath-выражением, содержащим тильды и результат подзапроса. Поскольку XPath-выражение начинается с тильды, оно синтаксически неверно, и MySQL возвращает ошибку вида: XPATH syntax error: '~1~'. Если вместо 1 подставить запрос к таблицам, в ошибке отобразятся имена таблиц или другие данные.
Пример ошибки: XPATH syntax error: '~users~' — так злоумышленник узнаёт имя таблицы.
Зачем это нужно злоумышленнику?
Error-based SQL-инъекции — один из самых быстрых способов извлечения данных из базы, когда приложение выводит сообщения об ошибках СУБД на страницу. В отличие от blind-инъекций, где приходится задавать множество вопросов «да/нет», здесь достаточно одного запроса, чтобы получить целую строку данных. EXTRACTVALUE и аналогичная функция UPDATEXML часто используются именно для этой цели в MySQL.
Как защититься?
Основные меры:
- Параметризованные запросы (prepared statements) — самый надёжный способ. Данные пользователя передаются отдельно от SQL-кода и не могут изменить структуру запроса.
- Отключение вывода ошибок СУБД — на продакшене сообщения об ошибках не должны показываться пользователю. Логирование ошибок в файл, а не в браузер.
- Валидация и экранирование — если параметризация невозможна, используйте строгую проверку типов и экранирование специальных символов.
- Принцип наименьших привилегий — учётная запись приложения должна иметь доступ только к необходимым таблицам и операциям.
- Регулярные сканирования уязвимостей — используйте SAST/DAST-инструменты для поиска SQL-инъекций.
Технические детали
Функция EXTRACTVALUE в MySQL принимает два аргумента: XML-документ и XPath-выражение. Если XPath-выражение содержит недопустимые символы (например, тильду), MySQL генерирует ошибку, включающую фрагмент этого выражения. Это и позволяет извлекать данные. Аналогично работает UPDATEXML. В более новых версиях MySQL (начиная с 5.7) эти функции помечены как устаревшие, но всё ещё доступны. В MariaDB они также присутствуют.
Стоит отметить, что подобные инъекции возможны не только в MySQL. В других СУБД есть свои функции для error-based атак, например, CAST в PostgreSQL или UTL_INADDR в Oracle. Однако EXTRACTVALUE — это «классика» именно для MySQL.
Пример реальной атаки
Предположим, есть уязвимый параметр id в URL: http://example.com/product.php?id=1. Запрос в коде: SELECT * FROM products WHERE id = '$id'. Злоумышленник подставляет:
1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e))-- -
В ответе сервера появится ошибка с версией MySQL. Далее можно извлекать имена таблиц, столбцов и сами данные.
Вывод
Строка ' OR EXTRACTVALUE(2746,CONCAT(0x7e,((SELECT (ELT(2746=2746,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции. Она демонстрирует, как через функцию EXTRACTVALUE можно заставить MySQL выдать данные в сообщении об ошибке. Понимание таких атак помогает разработчикам и специалистам по безопасности правильно защищать веб-приложения. Никогда не используйте подобные строки на чужих ресурсах — это незаконно. Применяйте полученные знания только для защиты своих систем.
Комментарии
—Войдите, чтобы оставить комментарий