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

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

Подобные строки часто встречаются в логах веб-серверов, в отчётах систем обнаружения вторжений (IDS) или в базах данных уязвимостей. Понимание их структуры помогает разработчикам и специалистам по безопасности лучше защищать свои приложения.

Разбор структуры эксплойта

Давайте разберём каждый элемент этой инъекции:

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

Функция EXTRACTVALUE

EXTRACTVALUE(XML_frag, XPath_expr) — это встроенная функция MySQL, которая возвращает текст первого текстового узла, найденного по XPath-выражению. Если XPath-выражение не находит совпадений или XML-фрагмент содержит ошибку, функция возвращает ошибку.

Злоумышленники используют эту особенность: они передают в качестве XPath-выражения строку, содержащую запрещённые символы (например, ~), что вызывает ошибку с текстом, включающим результат подзапроса. Таким образом, данные извлекаются через сообщения об ошибках.

Функция CONCAT и шестнадцатеричные литералы

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

Подзапрос с ELT

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

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

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

В данном примере:

  1. Приложение формирует SQL-запрос, включая в него пользовательский ввод без должной обработки.
  2. Внедрённый код закрывает строку и добавляет вызов EXTRACTVALUE с подзапросом.
  3. MySQL выполняет запрос, и из-за некорректного XPath возникает ошибка.
  4. Сообщение об ошибке содержит результат подзапроса (в данном случае 1), который выводится приложением.

Цели злоумышленников

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

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

Защита от SQL-инъекций, включая error-based, строится на нескольких принципах:

  • Использование подготовленных выражений (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не включаются в текст запроса напрямую.
  • Экранирование специальных символов с помощью функций, предоставляемых драйвером базы данных (например, mysqli_real_escape_string в PHP).
  • Отключение вывода ошибок СУБД на страницы приложения. Ошибки должны логироваться, но не показываться пользователю.
  • Ограничение прав пользователя базы данных, от имени которого работает приложение. Не используйте учётную запись с правами администратора.
  • Регулярное обновление СУБД и фреймворков для устранения известных уязвимостей.
  • Использование WAF (Web Application Firewall) для фильтрации подозрительного трафика.

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

Вместо конкатенации строк используйте параметризованные запросы. Например, в PHP с PDO:

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

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

Заключение

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

Источники