Введение

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

Что такое SQL-инъекция?

SQL-инъекция (SQL injection) — один из самых распространённых способов атаки на веб-приложения, при котором злоумышленник внедряет произвольный SQL-код в запросы к базе данных. Это становится возможным, если приложение не фильтрует пользовательский ввод должным образом. Существует несколько разновидностей SQL-инъекций: union-based, boolean-based, time-based и error-based. Наш случай относится к последней.

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

Разбор полезной нагрузки

Давайте последовательно разберём каждый компонент строки %')))) AND EXTRACTVALUE(9059,CONCAT(0x7e,((SELECT (ELT(9059=9059,1)))),0x7e))-- -.

1. Начальные символы: %'))))

Строка начинается с %')))). Символ % часто используется в URL-кодировании, но здесь он, скорее всего, является частью входных данных, которые не были должным образом экранированы. Далее идёт одинарная кавычка ', которая закрывает предыдущую строковую константу в уязвимом SQL-запросе. Затем следуют четыре закрывающие скобки )))). Они предназначены для закрытия открытых скобок в оригинальном запросе, чтобы внедряемый код оказался на верхнем уровне и не вызвал синтаксическую ошибку. Точное количество скобок зависит от структуры исходного запроса, и атакующий подбирает его экспериментально.

2. Логический оператор AND

После закрывающих скобок идёт AND. Это говорит о том, что злоумышленник пытается добавить условие к существующему выражению WHERE. Оператор AND позволяет объединить внедряемое условие с оригинальным, чтобы запрос оставался синтаксически корректным.

3. Функция EXTRACTVALUE

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

В нашем случае первым аргументом является число 9059. Это не XML, но MySQL автоматически преобразует его в строку. Второй аргумент — результат функции CONCAT.

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

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

5. Подзапрос с ELT и условием 9059=9059

Выражение ELT(9059=9059, 1) заслуживает отдельного внимания. ELT — это функция MySQL, которая возвращает N-й элемент из списка. Первый аргумент — числовой индекс, второй и последующие — список строк. В нашем случае ELT(9059=9059, 1) вычисляет условие 9059=9059, которое всегда истинно и возвращает 1 (в MySQL истина — это 1). Таким образом, ELT(1, 1) вернёт первый элемент списка, то есть 1. Это простейший случай, демонстрирующий работу конструкции. В реальной атаке вместо 1 мог бы стоять подзапрос, извлекающий, например, имя пользователя или хеш пароля из системных таблиц.

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

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

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

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

SELECT * FROM users WHERE id = '%')))) AND EXTRACTVALUE(9059,CONCAT(0x7e,((SELECT (ELT(9059=9059,1)))),0x7e))-- -';

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

SELECT * FROM users WHERE id = '%')))) AND EXTRACTVALUE(9059,CONCAT(0x7e,((SELECT (ELT(9059=9059,1)))),0x7e))-- -';

MySQL выполнит функцию EXTRACTVALUE. Поскольку второй аргумент содержит символ ~, который не является допустимым XPath-выражением, будет сгенерирована ошибка. В тексте ошибки MySQL отобразит переданный XPath, то есть ~1~ (если подзапрос вернул 1). Таким образом, атакующий увидит в сообщении об ошибке результат выполнения подзапроса. В более сложных случаях вместо 1 может быть, например, (SELECT password FROM users LIMIT 1), и в ошибке отобразится хеш пароля.

Последствия и защита

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

Для защиты необходимо:

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

Важно отметить, что начиная с MySQL 8.0.17 функция EXTRACTVALUE была удалена, что делает данный вектор атаки неработоспособным на новых версиях. Однако старые установки по-прежнему уязвимы.

Заключение

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

Источники