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

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

Важно понимать: приведённый код предназначен исключительно для образовательных целей. Использование SQL-инъекций для атаки на чужие системы является незаконным и преследуется по закону.

Контекст: SQL-инъекции и error-based техника

SQL-инъекция (SQLi) — один из самых распространённых способов взлома веб-приложений. Злоумышленник внедряет в запрос к базе данных специально сформированные фрагменты SQL-кода, чтобы изменить логику исходного запроса, получить доступ к данным или выполнить произвольные команды. Согласно рейтингу OWASP, инъекции остаются в топ-10 угроз веб-приложений.

Техника error-based (инъекция на основе ошибок) заключается в том, что атакующий заставляет базу данных вернуть сообщение об ошибке, содержащее полезную информацию. Если приложение выводит ошибки СУБД пользователю, это становится каналом утечки данных. Функция EXTRACTVALUE как раз и используется для генерации таких ошибок.

Разбор полезной нагрузки по частям

Рассмотрим каждый элемент запроса:

  • )) — два символа закрывающей скобки. Они нужны, чтобы «закрыть» ранее открытые скобки в оригинальном запросе приложения. Это позволяет внедрить свой код в правильный синтаксический контекст.
  • AND — логический оператор, который добавляет условие к существующему выражению WHERE. Если внедрённое условие истинно, исходный запрос выполнится; если ложно — нет. Это позволяет проводить слепые инъекции, но в данном случае используется error-based.
  • EXTRACTVALUE(9355, CONCAT(...)) — вызов функции MySQL для извлечения значения из XML-фрагмента. Первый аргумент (9355) — это XML-документ (число, которое будет интерпретировано как текст). Второй аргумент — XPath-выражение, сформированное динамически. Если XPath-выражение некорректно, MySQL выдаёт ошибку, в тексте которой может оказаться результат вычисления вложенного запроса.
  • CONCAT(0x7e, ((SELECT (ELT(9355=9355,1)))), 0x7e) — конкатенация трёх частей: шестнадцатеричного маркера 0x7e (символ «~»), результата подзапроса и снова маркера. Символ «~» используется как разделитель, чтобы облегчить извлечение данных из сообщения об ошибке.
  • SELECT (ELT(9355=9355,1)) — подзапрос, возвращающий результат функции ELT. ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь N — это результат сравнения 9355=9355, который всегда истинен (1). Таким образом, ELT(1,1) возвращает строку '1'. Это уловка, чтобы получить предсказуемое значение. В реальной атаке вместо '1' мог бы быть, например, пароль пользователя, полученный из другого подзапроса.
  • -- - — комментарий в SQL. Два дефиса начинают комментарий, а пробел и дефис добавлены для надёжности (некоторые парсеры требуют пробела после --). Всё, что идёт после, игнорируется, что позволяет отбросить оставшуюся часть оригинального запроса.

В результате выполнения такого запроса MySQL попытается вычислить XPath-выражение, содержащее символ «~» и результат подзапроса. Поскольку XPath не допускает подобных конструкций, будет сгенерирована ошибка вида: XPATH syntax error: '~1~'. Если приложение отображает эту ошибку, атакующий увидит значение '1'. В более сложных payload'ах вместо '1' подставляется конкатенация данных из базы, например, логин и пароль.

Зачем используется ELT и условие 9355=9355?

Конструкция ELT(9355=9355,1) — это простейший способ получить константное значение. Сравнение числа с самим собой всегда даёт истину (1), поэтому ELT возвращает первый элемент списка — строку '1'. В реальных атаках вместо этого могут быть более сложные подзапросы, например, ELT(1=1, (SELECT password FROM users LIMIT 1)). Но в данном примере показан минимальный шаблон, демонстрирующий синтаксис.

Такой подход позволяет обойти фильтры, если они блокируют прямые кавычки или определённые ключевые слова. Использование шестнадцатеричных литералов (0x7e) вместо символа '~' — тоже способ обфускации.

Как работает EXTRACTVALUE в MySQL

Функция EXTRACTVALUE(XML_document, XPath_expression) возвращает текст из XML-документа, соответствующий XPath-выражению. Если XPath-выражение некорректно, генерируется ошибка. Именно на этом и строится эксплойт: злоумышленник формирует XPath, который заведомо содержит недопустимые символы (например, «~»), и в тексте ошибки появляется результат вычисления вложенного запроса. Этот метод был особенно популярен в MySQL версий 5.1–5.7; в более новых версиях (8.0+) поведение может отличаться, но принцип остаётся.

Важно: начиная с MySQL 8.0.17, функция EXTRACTVALUE помечена как устаревшая (deprecated) и может быть удалена в будущих версиях. Однако она всё ещё встречается в старых системах.

Как защититься от подобных инъекций

Основной способ защиты — использование параметризованных запросов (prepared statements). Они не позволяют внедрять произвольный SQL-код, так как данные передаются отдельно от структуры запроса.

Дополнительные меры:

  • Экранирование специальных символов (хотя это менее надёжно, чем параметризация).
  • Ограничение прав пользователя базы данных: приложение должно работать с минимально необходимыми привилегиями.
  • Отключение вывода подробных сообщений об ошибках СУБД в production-окружении.
  • Использование веб-фаервола (WAF) для блокировки подозрительных конструкций.
  • Регулярное обновление СУБД и фреймворков.

Разработчикам также следует избегать динамического конструирования SQL-запросов на основе пользовательского ввода без должной проверки.

Заключение

Запрос )) AND EXTRACTVALUE(9355,CONCAT(0x7e,((SELECT (ELT(9355=9355,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции, демонстрирующий использование функций EXTRACTVALUE, CONCAT и ELT для извлечения данных через сообщения об ошибках. Понимание таких техник необходимо специалистам по безопасности для эффективной защиты веб-приложений. Помните: применение подобных знаний к чужим системам без разрешения является нарушением закона.

Источники