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

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

Внешне строка выглядит как набор случайных символов, но на самом деле это тщательно сконструированный запрос, который заставляет сервер базы данных выдать конфиденциальную информацию в тексте ошибки. Давайте разберём её по частям.

Анатомия инъекции

Начало: закрывающие скобки и кавычки

Фрагмент ")))) в начале — это попытка закрыть все открытые скобки и кавычки в оригинальном SQL-запросе, чтобы внедрить свой код. Злоумышленник предполагает, как выглядит уязвимый запрос, и подбирает количество закрывающих символов, чтобы «выровнять» синтаксис.

Функция EXTRACTVALUE

EXTRACTVALUE(3411, CONCAT(0x7e, ((SELECT (ELT(3411=3411,1)))), 0x7e)) — это вызов встроенной функции MySQL для работы с XML. Она извлекает значение из XML-документа по заданному XPath-выражению. Если XPath-выражение синтаксически неверно, MySQL выдаёт ошибку, в которой отображается переданное выражение. Именно это и используется для вывода данных.

CONCAT и 0x7e

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

SELECT и ELT

SELECT (ELT(3411=3411,1)) — это подзапрос, который возвращает результат выражения ELT(3411=3411,1). Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь 3411=3411 — это всегда истинное условие, которое в MySQL возвращает 1. Таким образом, ELT(1,1) вернёт строку «1». В реальной атаке вместо этого подзапроса подставляются другие выражения для извлечения имён таблиц, колонок или данных.

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

В конце стоит -- -. Двойной дефис с пробелом — это комментарий в SQL, который отсекает оставшуюся часть оригинального запроса, чтобы не нарушать синтаксис.

Как это работает на практике

Предположим, уязвимый запрос выглядит так:

SELECT * FROM users WHERE id = '")))) AND EXTRACTVALUE(3411,CONCAT(0x7e,((SELECT (ELT(3411=3411,1)))),0x7e))-- -'

После подстановки пользовательского ввода запрос превращается в:

SELECT * FROM users WHERE id = '"')))) AND EXTRACTVALUE(3411,CONCAT(0x7e,((SELECT (ELT(3411=3411,1)))),0x7e))-- -'

СУБД выполняет запрос. Функция EXTRACTVALUE получает неверный XPath (потому что внутри CONCAT образуется строка, не являющаяся корректным XPath), и MySQL возвращает ошибку вида:

XPATH syntax error: '~1~'

В этом сообщении мы видим результат выполнения подзапроса — «1». Если вместо ELT(3411=3411,1) подставить, например, SELECT version(), то в ошибке отобразится версия MySQL. Так злоумышленник может пошагово извлекать любые данные.

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

Error-based SQL-инъекции позволяют атакующему:

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

Особенность error-based подхода в том, что результат виден прямо в ответе сервера, что делает атаку очень быстрой и удобной для автоматизации.

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

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

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

  • Экранирование специальных символов с помощью функций вроде mysqli_real_escape_string (но это менее надёжно, чем параметризация).
  • Использование ORM (например, Doctrine, Hibernate), которые по умолчанию применяют параметризацию.
  • Ограничение прав пользователя базы данных: не давайте приложению прав на чтение information_schema без необходимости.
  • Включение логирования ошибок на стороне сервера и отключение вывода подробных ошибок в клиентский ответ.
  • Регулярное сканирование кода и пентесты.

Важно понимать, что EXTRACTVALUE — не единственная функция, используемая в error-based атаках. Аналогично применяются UPDATEXML, GTID_SUBSET и другие. Поэтому защита должна быть комплексной.

Заключение

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

Источники