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

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

В данном случае используется функция EXTRACTVALUE(), которая извлекает значение из XML-строки. Если передать ей некорректный XPath-запрос, MySQL сгенерирует ошибку, содержащую результат подзапроса. Это позволяет атакующему «прочитать» данные из базы.

Как работает error-based SQL-инъекция?

Error-based инъекция — это метод, при котором злоумышленник намеренно вызывает ошибку базы данных, чтобы в тексте ошибки увидеть полезную информацию. В MySQL для этого часто применяются функции EXTRACTVALUE() и UPDATEXML(). Они принимают два аргумента: XML-документ и XPath-выражение. Если XPath синтаксически неверен, СУБД возвращает сообщение вида XPATH syntax error: '...', где вместо многоточия подставляется переданная строка.

В нашем примере:

  • 7524 — произвольное число (идентификатор), которое не влияет на логику, но нужно для синтаксиса функции.
  • CONCAT(0x7e, ((SELECT (ELT(7524=7524,1)))), 0x7e) — конкатенация тильды (0x7e — это символ ~), результата подзапроса и ещё одной тильды. Тильды служат маркерами, чтобы в сообщении об ошибке было легко найти выводимые данные.
  • ELT(7524=7524,1) — функция ELT() возвращает N-й элемент из списка. Здесь условие 7524=7524 всегда истинно (1), поэтому возвращается первый элемент — число 1. Это простейшая проверка, которая в реальных атаках заменяется на извлечение имён таблиц, колонок или паролей.
  • -- - — комментарий, который обрезает оставшуюся часть оригинального SQL-запроса, чтобы не возникло синтаксической ошибки.

В результате MySQL выполнит функцию EXTRACTVALUE(7524, '~1~'), что вызовет ошибку: XPATH syntax error: '~1~'. Атакующий видит эту ошибку и понимает, что инъекция сработала. Далее он может подставлять в подзапрос другие выражения, например (SELECT database()), чтобы получить имя текущей базы данных.

Зачем это нужно злоумышленнику?

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

Строка с EXTRACTVALUE — это лишь один из многих шаблонов. В реальных атаках вместо ELT(7524=7524,1) подставляются сложные подзапросы, которые посимвольно извлекают данные. Например, чтобы узнать имя пользователя, атакующий может использовать SUBSTRING((SELECT user()),1,1) и перебирать символы.

Как защититься от SQL-инъекций?

Основной способ защиты — использование параметризованных запросов (prepared statements). Это позволяет отделить код SQL от данных, и никакая инъекция не сработает. Дополнительные меры:

  1. Экранирование специальных символов — но это менее надёжно, чем параметризация.
  2. Валидация входных данных — проверка типов, длины, допустимых символов.
  3. Ограничение прав пользователя БД — учётная запись приложения не должна иметь прав на чтение системных таблиц или выполнение опасных функций.
  4. Отключение вывода ошибок БД — на продакшене ошибки не должны показываться пользователю.
  5. Использование WAF — веб-application firewall может блокировать подозрительные запросы, но не является панацеей.

Важно регулярно обновлять СУБД и фреймворки, так как в старых версиях могут быть уязвимости, упрощающие эксплуатацию.

Пример безопасного кода на PHP

Вместо конкатенации строк используйте подготовленные выражения:

$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute(['id' => $userId]);

Такой подход гарантирует, что пользовательский ввод никогда не будет интерпретирован как SQL-код.

Заключение

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

Источники