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

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

Подобные строки часто встречаются в логах веб-сервера, в полях ввода форм или в параметрах URL. Они не являются случайным набором символов — это тщательно сконструированный запрос, цель которого заставить базу данных выдать скрытую информацию.

Разбор payload по частям

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

1. Начало: ')

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

2. AND

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

3. EXTRACTVALUE(4075, ...)

EXTRACTVALUE — функция MySQL для работы с XML. Она извлекает значение из XML-строки по указанному XPath-выражению. Синтаксис: EXTRACTVALUE(XML_document, XPath_expression).

Первый аргумент — 4075 — это просто число, которое будет интерпретировано как XML-документ. Оно не является корректным XML, что и вызовет ошибку. Второй аргумент — результат CONCAT — содержит XPath-выражение, которое также некорректно.

4. CONCAT(0x7e, ..., 0x7e)

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

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

5. ELT(4075=4075, 1)

ELT — функция MySQL, возвращающая N-й элемент из списка. Синтаксис: ELT(N, строка1, строка2, ...). Если N=1, возвращается первая строка.

Выражение 4075=4075 всегда истинно, что в MySQL даёт 1. Таким образом, ELT(1, 1) вернёт строку '1'. В реальных атаках вместо 1 подставляют подзапросы, например (SELECT version()), чтобы извлечь версию СУБД.

6. Завершение: -- -

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

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

Когда MySQL выполняет EXTRACTVALUE с некорректным XML, он генерирует ошибку вида:

XPATH syntax error: '~1~'

В сообщении об ошибке отображается результат вычисления второго аргумента. Если вместо 1 подставить, например, (SELECT database()), то в ошибке появится имя текущей базы данных. Так злоумышленник может посимвольно извлекать любые данные: имена таблиц, столбцов, логины, пароли.

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

Error-based инъекции — один из самых быстрых способов получить информацию из базы. Они не требуют слепого перебора и часто срабатывают даже при минимальном выводе ошибок. Если сайт отображает SQL-ошибки пользователю, атакующий может быстро выкачать всю базу.

В примере с 4075=4075 и ELT(...,1) — это тестовый payload. Злоумышленник проверяет, уязвим ли параметр. Если ошибка появляется, значит, инъекция возможна, и далее следуют более сложные запросы.

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

  • Используйте подготовленные выражения (prepared statements) — это самый надёжный способ. Параметры передаются отдельно от SQL-кода, и инъекция становится невозможной.
  • Экранируйте спецсимволы — если подготовленные выражения недоступны, применяйте функции экранирования, например mysqli_real_escape_string.
  • Отключите вывод ошибок — не показывайте пользователям текст SQL-ошибок. Логируйте их, но не выводите в браузер.
  • Ограничьте права БД — пользователь, от имени которого работает приложение, не должен иметь прав на чтение системных таблиц или выполнение опасных функций.
  • Используйте WAF — веб-приложения-фаерволы могут блокировать подозрительные конструкции вроде EXTRACTVALUE.

Итог

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

Источники