Что это за строка?
Строка ')) AND EXTRACTVALUE(8704,CONCAT(0x7e,((SELECT (ELT(8704=8704,1)))),0x7e))-- - — это классический пример SQL-инъекции (SQL injection), нацеленной на базу данных MySQL. Подобные конструкции часто встречаются в логах веб-серверов, в полях ввода форм или в параметрах URL. Их основная цель — проверить, уязвимо ли приложение перед внедрением вредоносного SQL-кода, и при возможности извлечь данные из базы.
В данной статье мы разберём, из чего состоит этот запрос, как работает каждый его элемент и какие меры защиты помогут предотвратить подобные атаки.
Расшифровка компонентов инъекции
Рассмотрим каждый элемент по порядку.
1. ')) — закрытие исходного выражения
Два символа ) и одинарная кавычка ' используются для того, чтобы «закрыть» ранее открытые скобки и строковый литерал в оригинальном SQL-запросе. Злоумышленник предполагает, что приложение подставляет пользовательский ввод внутрь запроса, например: SELECT * FROM users WHERE name = ('$input'). Вставив ')), атакующий пытается завершить оригинальное выражение и добавить своё условие.
2. AND EXTRACTVALUE(...) — вызов функции
EXTRACTVALUE — это встроенная функция MySQL, предназначенная для извлечения значения из XML-документа. Однако в контексте SQL-инъекций она используется иначе: при передаче некорректного XPath-выражения функция генерирует ошибку, в текст которой попадает результат вычисления переданного аргумента. Это позволяет злоумышленнику «прочитать» данные из базы через сообщения об ошибках (техника error-based SQL injection).
Первый аргумент — 8704 — это просто число, которое будет использовано как XML-документ (фактически не является корректным XML, что и вызовет ошибку). Второй аргумент — CONCAT(...) — формирует строку, которая попадёт в сообщение об ошибке.
3. CONCAT(0x7e, ..., 0x7e) — обёртка с тильдами
0x7e — это шестнадцатеричное представление символа ~ (тильда). Функция CONCAT объединяет строки. Тильды добавляются по краям, чтобы в сообщении об ошибке было легко найти внедрённые данные: они будут окружены символами ~. Это упрощает автоматический парсинг ответа сервера.
4. (SELECT (ELT(8704=8704,1))) — подзапрос с ELT
ELT(N, str1, str2, ...) — функция MySQL, которая возвращает N-ю строку из списка. В данном случае ELT(8704=8704, 1) возвращает 1, если условие 8704=8704 истинно (а оно всегда истинно). Фактически это тестовый запрос: он проверяет, что инъекция выполняется и функция ELT доступна. Если ошибка возникает, значит, приложение уязвимо. В реальной атаке вместо 8704=8704 могло бы быть условие, проверяющее, например, первый символ имени пользователя, и тогда возвращаемое значение зависело бы от данных.
5. -- - — комментарий
Два дефиса и пробел (или дефис) обозначают начало комментария в SQL. Всё, что идёт после, игнорируется базой данных. Это нужно, чтобы «отрезать» оставшуюся часть оригинального запроса, которая могла бы вызвать синтаксическую ошибку.
Как работает атака целиком
Когда уязвимое приложение подставляет эту строку в SQL-запрос, итоговый запрос может выглядеть примерно так:
SELECT * FROM products WHERE id = ('1')) AND EXTRACTVALUE(8704,CONCAT(0x7e,((SELECT (ELT(8704=8704,1)))),0x7e))-- -')
База данных выполняет следующее:
- Закрывает исходное выражение и добавляет условие
AND EXTRACTVALUE(...). - Вычисляет
ELT(8704=8704,1)→ получает1. - Формирует строку
~1~(тильда, единица, тильда). - Вызывает
EXTRACTVALUE(8704, '~1~'), что приводит к ошибке вида:XPATH syntax error: '~1~'. - Приложение, если оно выводит ошибки базы данных пользователю, показывает этот текст. Злоумышленник видит, что инъекция сработала, и может заменить
ELT(8704=8704,1)на подзапрос, извлекающий реальные данные (например,SELECT password FROM users LIMIT 1).
Таким образом, данная строка — это разведочный тест, а не финальная атака. Её задача — убедиться в наличии уязвимости и в возможности использовать error-based технику.
Почему это опасно?
SQL-инъекции остаются одной из самых распространённых угроз веб-приложений (входят в топ OWASP). Успешная эксплуатация позволяет злоумышленнику:
- читать произвольные данные из базы (учётные записи, персональные данные, платёжную информацию);
- модифицировать или удалять данные;
- обходить аутентификацию и получать доступ к административным функциям;
- в некоторых случаях — выполнять команды на сервере.
Конструкции с EXTRACTVALUE особенно удобны для атакующих, потому что не требуют вывода данных в ответе приложения — достаточно лишь сообщения об ошибке. Даже если приложение не показывает ошибки, злоумышленник может использовать слепые (blind) методы, но это уже сложнее.
Как защититься
Основные меры противодействия SQL-инъекциям хорошо известны:
- Параметризованные запросы (prepared statements). Это самый надёжный способ: данные передаются отдельно от кода SQL и не могут изменить структуру запроса.
- Экранирование пользовательского ввода. Если по каким-то причинам нельзя использовать параметризацию, применяйте функции экранирования, предоставляемые драйвером базы данных (например,
mysqli_real_escape_stringв PHP). - Валидация и белые списки. Проверяйте, что входные данные соответствуют ожидаемому формату (число, дата, идентификатор из списка).
- Минимальные привилегии для учётной записи БД. Пользователь базы, от имени которого работает приложение, должен иметь только необходимые права (обычно SELECT, INSERT, UPDATE, DELETE для конкретных таблиц).
- Отключение вывода ошибок БД в production. Сообщения об ошибках должны логироваться, но не отображаться пользователю.
- Использование WAF (Web Application Firewall). Может помочь отфильтровать известные шаблоны атак, но не является заменой правильному кодированию.
Также рекомендуется проводить регулярные аудиты кода и сканирования уязвимостей.
Заключение
Строка ')) AND EXTRACTVALUE(8704,CONCAT(0x7e,((SELECT (ELT(8704=8704,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции в MySQL. Она использует функцию EXTRACTVALUE для генерации ошибки, содержащей результат подзапроса, и функцию ELT для проверки условия. Понимание механики таких атак помогает разработчикам и администраторам лучше защищать свои приложения. Если вы встретили подобную строку в логах, это повод проверить код на наличие уязвимостей и внедрить параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий