Что это за запрос?
Пользовательский запрос %'))) AND EXTRACTVALUE(8118,CONCAT(0x7e,((SELECT (ELT(8118=8118,1)))),0x7e))-- - представляет собой классический пример SQL-инъекции на основе ошибок (error-based SQL injection). Такие запросы часто встречаются в логах веб-серверов и свидетельствуют о попытках злоумышленников получить доступ к данным базы данных через уязвимые параметры приложения.
В данной статье мы разберём каждый элемент этого запроса, объясним, как работает эксплойт, какие данные пытаются извлечь, и как защититься от подобных атак.
Расшифровка компонентов инъекции
Запрос состоит из нескольких частей, каждая из которых играет свою роль в атаке.
1. Начальные символы: %')))
Символ % в начале часто используется для обхода фильтров или как часть URL-кодирования. Далее идут закрывающие кавычка и скобки: '))). Это попытка «закрыть» исходный SQL-запрос, чтобы внедрить свой код. Количество скобок может варьироваться в зависимости от структуры уязвимого запроса.
2. Оператор AND
Используется для добавления условия к существующему запросу. Если исходный запрос возвращает данные, то добавление AND с функцией, вызывающей ошибку, позволяет злоумышленнику определить, выполняется ли инъекция.
3. Функция EXTRACTVALUE(8118, CONCAT(...))
EXTRACTVALUE — это функция MySQL, предназначенная для извлечения значения из XML-документа. Однако она часто используется в атаках, потому что при передаче некорректного XPath-выражения вызывает ошибку, в текст которой попадает переданная строка. Это позволяет злоумышленнику извлекать данные через сообщения об ошибках.
Первый аргумент 8118 — это XML-документ (число, которое будет преобразовано в строку). Второй аргумент — XPath-выражение, которое формируется с помощью CONCAT.
4. Конкатенация с тильдой: CONCAT(0x7e, ..., 0x7e)
0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильда используется как маркер, чтобы облегчить поиск извлечённых данных в сообщении об ошибке. Конкатенация обрамляет полезную нагрузку с двух сторон, чтобы потом можно было легко вычленить результат.
5. Внутренний подзапрос: (SELECT (ELT(8118=8118,1)))
Здесь используется функция ELT (Extract List Item). ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В данном случае ELT(8118=8118, 1) — условие 8118=8118 всегда истинно (возвращает 1), поэтому ELT вернёт первый элемент списка, то есть 1. Это простой способ получить предсказуемое значение. В реальных атаках вместо 1 может быть подставлен подзапрос, извлекающий данные (например, имя пользователя или пароль).
6. Комментарий -- -
Два дефиса начинают комментарий в SQL, а пробел и дефис добавлены для корректного завершения комментария в некоторых СУБД (например, MySQL требует пробел после --). Всё, что идёт после комментария, игнорируется. Это позволяет отбросить оставшуюся часть исходного запроса, которая могла бы вызвать синтаксическую ошибку.
Как работает эксплойт
Предположим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE id = '$input'
Если передать в $input наш запрос, то после подстановки получится:
SELECT * FROM users WHERE id = '%'))) AND EXTRACTVALUE(8118,CONCAT(0x7e,((SELECT (ELT(8118=8118,1)))),0x7e))-- -'
База данных尝试 выполнить этот запрос. Сначала часть '%'))) закрывает строку и скобки, затем добавляется условие AND. Функция EXTRACTVALUE вызывается с аргументами, которые формируют XPath-выражение ~1~. Поскольку ~1~ не является допустимым XPath (начинается с тильды), MySQL выдаст ошибку, например:
XPATH syntax error: '~1~'
В сообщении об ошибке появится значение, переданное в CONCAT. В нашем случае это ~1~. Если вместо 1 подставить подзапрос, например, (SELECT password FROM users LIMIT 1), то в ошибке отобразится пароль. Так злоумышленник может извлекать данные посимвольно или целыми строками.
Комментарий -- - отсекает оставшуюся часть исходного запроса (закрывающую кавычку), чтобы избежать синтаксической ошибки.
Зачем используется ELT с всегда истинным условием?
В данном примере ELT(8118=8118,1) — это демонстрация подхода. В реальных атаках злоумышленники могут использовать ELT для возврата разных значений в зависимости от условия. Например, ELT(1=1, 'a', 'b') вернёт 'a', а ELT(1=2, 'a', 'b') вернёт 'b'. Это позволяет реализовать слепую инъекцию, когда данные извлекаются по принципу «да/нет». Однако в нашем случае условие всегда истинно, поэтому возвращается фиксированное значение.
Какие данные пытаются извлечь?
В представленном запросе извлекается просто число 1. Это тестовый запрос, чтобы проверить, работает ли инъекция. Если ошибка возвращается, злоумышленник понимает, что уязвимость есть, и может заменить 1 на подзапрос, извлекающий конфиденциальные данные: имена пользователей, хеши паролей, номера кредитных карт и т.д.
Как защититься от SQL-инъекций
Основная причина успеха таких атак — недостаточная фильтрация пользовательского ввода и динамическое построение SQL-запросов. Вот ключевые меры защиты:
- Использование параметризованных запросов (prepared statements). Это самый надёжный способ: данные передаются отдельно от SQL-кода, и СУБД не интерпретирует их как часть запроса.
- Экранирование специальных символов. Если по каким-то причинам нельзя использовать параметризацию, применяйте функции экранирования (например,
mysqli_real_escape_stringв PHP). - Ограничение прав пользователя базы данных. Приложение должно подключаться к БД с минимально необходимыми привилегиями (обычно только SELECT, INSERT, UPDATE, DELETE для конкретных таблиц).
- Валидация ввода. Проверяйте, что входные данные соответствуют ожидаемому формату (числа, email, даты и т.д.).
- Использование ORM или query builder. Современные библиотеки для работы с БД часто автоматически используют параметризацию.
- Регулярное обновление СУБД и приложений. Устаревшие версии могут содержать уязвимости.
- Мониторинг и логирование. Подозрительные запросы, подобные описанному, должны фиксироваться и анализироваться.
Также рекомендуется проводить аудит кода и использовать сканеры уязвимостей для выявления потенциальных проблем.
Заключение
Запрос с EXTRACTVALUE и ELT — это типичный пример error-based SQL-инъекции, использующей особенности MySQL для извлечения данных через сообщения об ошибках. Понимание механики таких атак помогает разработчикам и администраторам правильно выстраивать защиту. Главное правило: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий