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

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

Разбор компонентов строки

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

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

Как работает EXTRACTVALUE для извлечения данных

Функция EXTRACTVALUE(XML_document, XPath_expression) возвращает текст из XML-документа по указанному XPath-выражению. Если XPath-выражение содержит недопустимые символы (например, тильду ~), MySQL генерирует ошибку вида: XPATH syntax error: '~результат~'. Именно это и нужно атакующему — он помещает результат подзапроса между двумя тильдами, чтобы ошибка вывела его на экран.

В нашем случае:

  • CONCAT(0x7e, ((SELECT (ELT(9906=9906,1)))), 0x7e) формирует строку ~1~, потому что 0x7e — это шестнадцатеричный код тильды, а ELT(9906=9906,1) возвращает 1, так как условие 9906=9906 истинно.
  • Затем EXTRACTVALUE(9906, '~1~') пытается интерпретировать число 9906 как XML-документ, что вызывает ошибку с текстом ~1~.

В реальной атаке вместо ELT(9906=9906,1) может стоять подзапрос, извлекающий, например, имя пользователя или хеш пароля из базы. Ошибка выведет эти данные.

Зачем злоумышленники используют такие строки?

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

Такие строки часто являются частью автоматизированных сканеров, например, SQLmap. Они перебирают множество вариаций, чтобы найти уязвимость. Если вы видите подобную строку в логах, это сигнал о попытке взлома.

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

Лучший способ защиты — использовать параметризованные запросы (prepared statements). Они разделяют код и данные, поэтому внедрение SQL-кода становится невозможным. Также рекомендуется:

  • Экранировать все пользовательские данные перед вставкой в SQL-запрос.
  • Использовать ORM (например, Doctrine, Hibernate), которые автоматически применяют параметризацию.
  • Отключить вывод ошибок базы данных на продакшене, чтобы злоумышленник не мог получить информацию через сообщения об ошибках.
  • Регулярно обновлять СУБД и фреймворки, чтобы закрыть известные уязвимости.
  • Применять WAF (Web Application Firewall) для фильтрации подозрительных запросов.

Что делать, если вы обнаружили такую строку в логах?

Если вы администратор сайта и нашли подобную строку в логах, это может означать, что ваш сайт пытались взломать. Не паникуйте, но примите меры:

  1. Проверьте, не была ли атака успешной. Ищите необычные записи в базе данных, изменения в файлах.
  2. Убедитесь, что все входные данные обрабатываются безопасно.
  3. Если сайт на CMS (WordPress, Joomla и т.д.), обновите ядро, плагины и темы.
  4. Рассмотрите возможность установки WAF, например, ModSecurity с правилами OWASP.
  5. Проведите аудит безопасности с помощью специалистов.

Заключение

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

Источники