Что такое EXTRACTVALUE и при чём тут SQL-инъекции?

Функция EXTRACTVALUE — это встроенная функция MySQL, предназначенная для работы с XML-документами. Она извлекает значение из XML-строки по указанному XPath-выражению. Синтаксис прост: EXTRACTVALUE(XML_фрагмент, XPath_выражение). Казалось бы, безобидный инструмент для парсинга XML. Однако именно эта функция стала одним из самых популярных векторов для error-based SQL-инъекций — атак, при которых злоумышленник заставляет базу данных возвращать данные прямо в сообщениях об ошибках.

В запросе из вашего вопроса: )) AND EXTRACTVALUE(6639,CONCAT(0x7e,((SELECT (ELT(6639=6639,1)))),0x7e))-- - — виден классический пример такой инъекции. Давайте разберём его по частям.

Анатомия вредоносного запроса

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

SELECT * FROM users WHERE id = (1);

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

Внутри EXTRACTVALUE используется функция CONCAT, которая склеивает символ ~ (0x7e), результат подзапроса и ещё один ~. Подзапрос SELECT (ELT(6639=6639,1)) возвращает 1, потому что условие 6639=6639 всегда истинно. ELT — это функция, возвращающая N-й элемент из списка; здесь она возвращает первый элемент — число 1.

В реальной атаке вместо ELT(6639=6639,1) подставляется запрос к системным таблицам, например:

EXTRACTVALUE(1, CONCAT(0x7e, (SELECT table_name FROM information_schema.tables LIMIT 0,1), 0x7e))

MySQL попытается интерпретировать результат CONCAT как XPath-выражение. Поскольку строка начинается с тильды, возникает ошибка вида: XPATH syntax error: '~имя_таблицы~'. Так злоумышленник получает имена таблиц, колонок и даже хеши паролей — по одной порции за каждый запрос.

Почему EXTRACTVALUE так популярен у пентестеров

  • Простота: не нужно возиться со слепыми инъекциями — данные возвращаются сразу в тексте ошибки.
  • Совместимость: функция доступна в MySQL 5.1+ и MariaDB, которые до сих пор широко используются.
  • Обход фильтров: многие WAF не блокируют EXTRACTVALUE, если не настроены специальные правила.
  • Скорость: один HTTP-запрос — одна порция данных, тогда как blind SQLi требует множества запросов.

Аналогичный трюк возможен с функцией UPDATEXML, которая также генерирует ошибки XPath. Обе функции часто встречаются в читерских листах по SQL-инъекциям.

Пример эксплуатации на DVWA

В учебном приложении DVWA (Damn Vulnerable Web Application) можно воспроизвести атаку. На уровне безопасности low в поле ввода подставляется:

1' AND EXTRACTVALUE(1, CONCAT(0x7e, (SELECT database()), 0x7e))-- 

В ответе появится ошибка с именем текущей базы данных. Далее перебираются таблицы, колонки и значения. Именно так работают инструменты вроде sqlmap — они автоматизируют этот процесс, но понимание ручной техники необходимо для отладки и обхода нестандартных фильтров.

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

Главное правило — никогда не доверять пользовательскому вводу. Конкретные меры:

  1. Параметризованные запросы (prepared statements). Это самый надёжный способ. Данные передаются отдельно от SQL-кода, и EXTRACTVALUE просто не сможет выполниться.
  2. Отключение вывода ошибок на продакшене. Если приложение не показывает детали ошибок MySQL, злоумышленник не увидит результат инъекции. Однако это не устраняет уязвимость, а лишь затрудняет эксплуатацию.
  3. Валидация и экранирование. Приведение типов (например, (int)$_GET['id']) и использование функций экранирования (mysqli_real_escape_string) снижают риск, но не дают 100% гарантии.
  4. WAF с правилами для EXTRACTVALUE. Современные веб-application firewall умеют блокировать подозрительные конструкции, но их нужно правильно настраивать.
  5. Регулярные аудиты и сканирование. Используйте сканеры уязвимостей и проводите пентесты, чтобы выявлять дыры до атакующих.
По данным OWASP, SQL-инъекции остаются в топ-10 критических угроз веб-приложений уже более десяти лет. Error-based инъекции через EXTRACTVALUE — лишь один из многих сценариев, но он наглядно демонстрирует, почему нельзя конкатенировать SQL-запросы с пользовательскими данными.

Итог

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

Источники