Что это за строка?

Строка '))) AND EXTRACTVALUE(9407,CONCAT(0x7e,((SELECT (ELT(9407=9407,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используются злоумышленниками для извлечения данных из базы данных через намеренно вызываемые ошибки, текст которых возвращается в ответе сервера.

Подобные строки часто встречаются в логах веб-серверов, в отчётах систем обнаружения вторжений (IDS) и в учебных материалах по безопасности. Понимание их структуры помогает разработчикам и администраторам распознавать атаки и правильно настраивать защиту.

Из чего состоит инъекция?

Разберём каждый элемент по порядку.

1. Префикс ')))

Начинается с апострофа и закрывающих скобок. Это попытка «закрыть» ранее открытые кавычки и скобки в исходном SQL-запросе, чтобы внедрить собственный код. Количество скобок подбирается экспериментально — в зависимости от структуры уязвимого запроса.

2. AND

Логический оператор, который добавляет условие к существующему запросу. Если исходный запрос был истинным, то после AND с внедрённым выражением результат может измениться, что позволяет атакующему влиять на логику выполнения.

3. EXTRACTVALUE(9407, ...)

Функция MySQL EXTRACTVALUE(XML_frag, XPath_expr) извлекает значение из фрагмента XML по заданному XPath-выражению. В контексте инъекции её используют для вызова ошибки, если второй аргумент содержит недопустимые символы. Сообщение об ошибке будет содержать переданную строку, что позволяет вывести данные.

Число 9407 — произвольный идентификатор (может быть любым), часто используется для уникализации или просто как случайное значение.

4. CONCAT(0x7e, ((SELECT (ELT(9407=9407,1)))), 0x7e)

Функция CONCAT объединяет строки. Здесь она собирает значение, которое будет передано в EXTRACTVALUE в качестве XPath-выражения. 0x7e — шестнадцатеричный код символа ~ (тильда). Тильда добавляется с двух сторон, чтобы гарантировать наличие недопустимого для XPath символа и вызвать ошибку, в тексте которой появится результат подзапроса.

Внутри CONCAT находится подзапрос SELECT (ELT(9407=9407,1)).

5. ELT(9407=9407,1)

ELT(N, str1, str2, ...) возвращает строку по номеру. Если N равно 1, возвращается str1, если 2 — str2 и т.д. Выражение 9407=9407 всегда истинно и в MySQL приводится к числу 1. Таким образом, ELT(9407=9407,1) всегда возвращает 1. Это простейший тест: если инъекция сработала, в ошибке появится ~1~. В реальных атаках вместо 1 подставляют подзапрос, извлекающий нужные данные (например, имя пользователя, хеш пароля).

6. Комментарий -- -

Символы -- начинают комментарий в SQL (в MySQL требуется, чтобы после двух дефисов был пробел или спецсимвол). Пробел и дефис в конце (-- -) гарантируют, что остаток исходного запроса будет проигнорирован. Это позволяет атакующему «отрезать» лишний код и сделать внедрённую конструкцию синтаксически корректной.

Как работает атака?

Уязвимость возникает, когда веб-приложение подставляет пользовательский ввод в SQL-запрос без должной обработки. Злоумышленник передаёт специально сформированную строку, которая изменяет логику запроса. В случае error-based инъекции результат выполнения подзапроса внедряется в сообщение об ошибке, которое возвращается клиенту (например, отображается на странице или попадает в лог).

Пример уязвимого запроса (псевдокод):

SELECT * FROM articles WHERE id = '$id'

Если передать $id = 1'))) AND EXTRACTVALUE(9407,CONCAT(0x7e,((SELECT (ELT(9407=9407,1)))),0x7e))-- -, то после подстановки получится:

SELECT * FROM articles WHERE id = '1'))) AND EXTRACTVALUE(9407,CONCAT(0x7e,((SELECT (ELT(9407=9407,1)))),0x7e))-- -'

СУБД выполнит запрос, вызовет функцию EXTRACTVALUE с некорректным XPath (из-за тильды) и вернёт ошибку вида:

XPATH syntax error: '~1~'

Так атакующий убеждается, что инъекция работает, и может заменить 1 на подзапрос, например (SELECT password FROM users LIMIT 1), чтобы извлечь конфиденциальные данные.

Почему это опасно?

  • Утечка данных: через ошибки можно получить имена таблиц, столбцов, логины, хеши паролей и другую чувствительную информацию.
  • Обход аутентификации: некоторые инъекции позволяют войти в систему без пароля.
  • Полный контроль над базой: в зависимости от привилегий пользователя БД возможны модификация и удаление данных.

Error-based инъекции особенно эффективны, когда приложение выводит подробные сообщения об ошибках. Даже если ошибки не отображаются пользователю, они могут попадать в логи, к которым иногда имеют доступ злоумышленники.

Как защититься?

  1. Параметризованные запросы (prepared statements): главный способ предотвращения SQL-инъекций. Никогда не конкатенируйте пользовательский ввод в SQL-код.
  2. Экранирование специальных символов: используйте встроенные функции экранирования (например, mysqli_real_escape_string в PHP), но помните, что это не панацея.
  3. Отключение подробных сообщений об ошибках: на production-серверах не выводите текст ошибок БД пользователю.
  4. Принцип наименьших привилегий: учётная запись, под которой работает приложение, должна иметь только необходимые права (обычно только SELECT/INSERT/UPDATE/DELETE для конкретных таблиц).
  5. Регулярное обновление СУБД и фреймворков: используйте актуальные версии, чтобы закрыть известные уязвимости.
  6. WAF (Web Application Firewall): может блокировать известные шаблоны атак, но не заменяет правильного кодирования.

В данном конкретном примере строка '))) AND EXTRACTVALUE(9407,CONCAT(0x7e,((SELECT (ELT(9407=9407,1)))),0x7e))-- - является тестовой: она не извлекает реальные данные, а лишь проверяет возможность инъекции. Однако она демонстрирует технику, которая при успехе может быть расширена для кражи информации.

Заключение

Рассмотренная конструкция — это типичный пример error-based SQL-инъекции для MySQL, использующей функцию EXTRACTVALUE для вывода данных через сообщение об ошибке. Понимание таких строк помогает специалистам по безопасности распознавать атаки, а разработчикам — избегать уязвимостей. Главная рекомендация: всегда используйте параметризованные запросы и не доверяйте пользовательскому вводу.

Источники