Что такое SQL-инъекция и при чём здесь EXTRACTVALUE

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

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

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

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

  • %') — попытка закрыть ранее открытую кавычку и скобку в оригинальном запросе приложения. Символ % часто используется в LIKE-запросах, поэтому такая комбинация помогает «разорвать» исходный SQL-код и добавить своё условие.
  • AND — логический оператор, который позволяет присоединить дополнительное условие к WHERE-клаузе. Если основное условие истинно, выполнится и внедрённая часть.
  • EXTRACTVALUE(2028, CONCAT(...)) — вызов встроенной функции MySQL для работы с XML. EXTRACTVALUE извлекает значение из XML-фрагмента по заданному XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, текст которой содержит переданные данные. Это и есть канал утечки.
  • 0x7e — шестнадцатеричное представление символа ~ (тильда). Он используется как маркер, чтобы в сообщении об ошибке было легко найти границы выведенных данных.
  • CONCAT(0x7e, ((SELECT (ELT(2028=2028,1)))), 0x7e) — конкатенация тильды, результата подзапроса и ещё одной тильды. В данном примере подзапрос возвращает число 1 (поскольку условие 2028=2028 всегда истинно, а ELT(1, 1) возвращает первый элемент списка). В реальной атаке на месте этого подзапроса может быть запрос к таблицам information_schema или пользовательским данным.
  • -- - — комментарий, который «отрезает» оставшуюся часть оригинального запроса, чтобы синтаксис стал корректным.

В результате выполнения такого запроса MySQL выдаст ошибку вида: XPATH syntax error: '~1~'. Злоумышленник, анализируя текст ошибки, получает искомое значение.

Функция EXTRACTVALUE: назначение и уязвимость

Сама по себе EXTRACTVALUE — легитимная функция MySQL, предназначенная для извлечения данных из XML-документов. Она принимает два аргумента: XML-строку и XPath-выражение. Однако если XPath-выражение содержит синтаксическую ошибку, сервер возвращает сообщение, включающее часть переданного выражения. Эту особенность и эксплуатируют атакующие: они передают в XPath результат подзапроса, а сервер «эхом» возвращает его в тексте ошибки.

Аналогичным образом работают и другие функции, например UPDATEXML или GEOMETRYCOLLECTION, но EXTRACTVALUE — один из самых популярных инструментов error-based инъекций.

Функция ELT и её роль

ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В приведённом примере ELT(2028=2028, 1) возвращает 1, так как условие истинно. В реальной атаке вместо 1 может стоять, например, (SELECT table_name FROM information_schema.tables LIMIT 1). Таким образом, ELT используется как «обёртка» для извлечения произвольных данных.

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

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

  • Экранирование специальных символов с помощью функций вроде mysqli_real_escape_string (для MySQL).
  • Валидация и фильтрация пользовательского ввода на основе белых списков.
  • Ограничение прав пользователя базы данных: приложение должно работать с минимально необходимыми привилегиями.
  • Отключение подробных сообщений об ошибках в production-окружении, чтобы не давать атакующему обратную связь.
  • Использование WAF (Web Application Firewall) для блокировки подозрительных запросов.

Важно понимать, что error-based инъекция — лишь один из многих методов. Злоумышленники также используют union-based, blind (boolean и time-based) и out-of-band инъекции. Поэтому защита должна быть комплексной.

Заключение

Строка %') AND EXTRACTVALUE(2028,CONCAT(0x7e,((SELECT (ELT(2028=2028,1)))),0x7e))-- - — это учебный пример эксплуатации уязвимости, который демонстрирует, как функции MySQL могут быть использованы для извлечения данных через сообщения об ошибках. Понимание механики таких атак помогает разработчикам и администраторам строить надёжную защиту и предотвращать утечки информации.

Источники