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

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

В данном конкретном случае выражение 4021=4021 всегда истинно, поэтому функция ELT(4021=4021,1) возвращает 1. Это простейший тестовый пример, который показывает, что инъекция работает. В реальной атаке вместо 1 подставляются имена таблиц, колонок или другие данные.

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

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

Функция EXTRACTVALUE

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

Злоумышленники эксплуатируют это: они передают в качестве XPath строку, содержащую результаты подзапроса, и когда MySQL пытается вычислить XPath, он выдаёт ошибку, включающую эту строку. Таким образом, данные «утекают» через сообщение об ошибке.

Разбор конкретной строки

Давайте разберём по частям:

  • ` — обратный апостроф, который часто используется для экранирования имён таблиц или колонок. В контексте инъекции он может закрывать предыдущее выражение.
  • AND — логический оператор, добавляемый к оригинальному запросу.
  • EXTRACTVALUE(4021, CONCAT(0x7e, ((SELECT (ELT(4021=4021,1)))), 0x7e)) — вызов функции с двумя аргументами. Первый аргумент 4021 — это произвольное число (может быть любым). Второй аргумент — результат CONCAT, который объединяет тильду (0x7e — шестнадцатеричный код символа ~), результат подзапроса и ещё одну тильду.
  • -- - — комментарий, который отсекает оставшуюся часть оригинального SQL-запроса, чтобы не вызвать синтаксическую ошибку.

Подзапрос SELECT (ELT(4021=4021,1)) возвращает 1, так как условие истинно. Функция ELT(N, str1, str2, ...) возвращает N-ю строку из списка. Здесь N=1 (истина), поэтому возвращается первая строка — 1. Затем CONCAT создаёт строку вида ~1~. EXTRACTVALUE пытается интерпретировать эту строку как XPath, терпит неудачу и генерирует ошибку: XPATH syntax error: '~1~'. В реальной атаке вместо 1 будет, например, version() или database().

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

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

Пример реальной атаки

Предположим, есть уязвимый параметр id в URL: http://example.com/product.php?id=1. Злоумышленник подставляет:

1` AND EXTRACTVALUE(4021,CONCAT(0x7e,(SELECT version()),0x7e))-- -

Если приложение уязвимо, оно вернёт ошибку вида: XPATH syntax error: '~5.7.34~'. Так узнаётся версия MySQL. Далее можно извлекать имена таблиц, колонок и сами данные.

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

Основные меры защиты:

  1. Использование подготовленных выражений (prepared statements) с параметризацией запросов. Это самый надёжный способ, так как данные не попадают напрямую в SQL-код.
  2. Экранирование специальных символов с помощью функций вроде mysqli_real_escape_string (для MySQL). Однако этот метод уступает параметризации.
  3. Отключение вывода ошибок БД на экран в production-окружении. Ошибки должны логироваться, но не показываться пользователю.
  4. Использование ORM (например, Doctrine, Hibernate), которые автоматически параметризуют запросы.
  5. Регулярное обновление СУБД и фреймворков для закрытия известных уязвимостей.
  6. Внедрение WAF (Web Application Firewall) для фильтрации подозрительных запросов.

Важно понимать, что error-based инъекция — лишь один из многих типов SQL-инъекций. Существуют также union-based, boolean-based, time-based. Комплексная защита должна покрывать все векторы.

Заключение

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

Источники