Что такое AND EXTRACTVALUE в SQL-инъекции?
Выражение " AND EXTRACTVALUE(3913,CONCAT(0x7e,((SELECT (ELT(3913=3913,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции (инъекции на основе ошибок). Злоумышленник внедряет в уязвимый параметр запроса конструкцию, которая заставляет СУБД MySQL сгенерировать ошибку, содержащую результат выполнения вложенного SQL-запроса. В данном случае проверяется истинность условия 3913=3913 — оно всегда истинно, поэтому функция ELT вернёт строку 1. Эта строка передаётся в EXTRACTVALUE вместе с символом тильды 0x7e в качестве разделителя, что приводит к ошибке формата XPATH, в тексте которой отобразится значение 1.
Подобные конструкции часто встречаются в отчётах об уязвимостях и в логах веб-серверов. Они не являются вредоносным кодом сами по себе, но служат индикатором попытки эксплуатации SQL-инъекции. Понимание механики таких запросов помогает разработчикам и администраторам правильно настраивать защиту и интерпретировать события безопасности.
Как работает функция EXTRACTVALUE в MySQL
Функция EXTRACTVALUE() появилась в MySQL 5.1 и предназначена для извлечения данных из XML-документов с помощью выражений XPath. Она принимает два строковых аргумента: фрагмент XML-разметки и XPath-локатор. Возвращает текст (CDATA) первого текстового узла, который является дочерним для элемента или элементов, соответствующих XPath-выражению.
Синтаксис: EXTRACTVALUE( xml_frag, xpath_expr ). Если XPath-выражение некорректно, функция генерирует ошибку.
Именно эта особенность используется в error-based инъекциях: злоумышленник подставляет в XPath-выражение результат подзапроса, и СУБД возвращает сообщение об ошибке, содержащее эти данные. Например, в нашем случае XPath-выражение формируется как CONCAT(0x7e, (SELECT ...), 0x7e), что даёт строку вида ~1~. Функция EXTRACTVALUE пытается интерпретировать её как XPath и терпит неудачу, выводя в ошибке полученную строку.
Разбор конкретной конструкции
Рассмотрим по частям выражение AND EXTRACTVALUE(3913,CONCAT(0x7e,((SELECT (ELT(3913=3913,1)))),0x7e))-- -:
- AND — логический оператор, который добавляется к условию WHERE исходного запроса. Если исходный запрос был истинным, добавление
ANDс функцией, вызывающей ошибку, приведёт к прерыванию выполнения и выводу сообщения об ошибке. - EXTRACTVALUE(3913, ...) — первый аргумент
3913— это произвольное число, которое будет интерпретировано как XML-фрагмент. Оно не является корректным XML, но это не важно, так как ошибка возникнет на этапе разбора XPath. - CONCAT(0x7e, ..., 0x7e) — объединяет символ тильды (
~, шестнадцатеричный код 0x7e) с результатом подзапроса. Тильда используется как маркер, чтобы облегчить поиск вывода в тексте ошибки. - SELECT (ELT(3913=3913,1)) — подзапрос, возвращающий строку
1. ФункцияELT(N, str1, str2, ...)возвращает N-ю строку из списка. Здесь N — результат сравнения3913=3913, то есть1(истина). Следовательно,ELT(1, 1)вернёт1. - -- - — комментарий, который отсекает оставшуюся часть исходного SQL-запроса, чтобы не нарушать синтаксис.
В результате MySQL попытается выполнить XPath-выражение ~1~, что вызовет ошибку вида XPATH syntax error: '~1~'. В тексте ошибки злоумышленник увидит 1 — это подтверждает, что инъекция работает и можно извлекать произвольные данные, подставляя вместо ELT(3913=3913,1) другие подзапросы.
Зачем это нужно злоумышленнику?
Error-based SQL-инъекции — один из самых быстрых способов извлечения информации из базы данных. В отличие от blind-инъекций, где данные получают по крупицам через логические условия, здесь сервер сам возвращает результат в сообщении об ошибке. Это позволяет за несколько запросов получить имена таблиц, столбцов, логины и пароли пользователей.
Конструкция с EXTRACTVALUE особенно популярна, потому что функция доступна во многих версиях MySQL и не требует специальных привилегий. Однако начиная с MySQL 5.7.9 она была объявлена устаревшей, а в MySQL 8.0 удалена. Тем не менее, на многих устаревших серверах она всё ещё работает, что делает этот вектор атаки актуальным.
Как защититься от таких инъекций?
Основной метод защиты — использование параметризованных запросов (prepared statements). Они разделяют код SQL и данные, поэтому внедрение произвольных конструкций становится невозможным. Дополнительные меры:
- Валидация и фильтрация всех входных данных, особенно тех, что попадают в SQL-запросы.
- Применение ORM или query builder с автоматическим экранированием.
- Ограничение прав пользователя базы данных: приложение должно работать от имени учётной записи с минимально необходимыми привилегиями.
- Регулярное обновление СУБД и отказ от устаревших функций, таких как
EXTRACTVALUE. - Использование WAF (Web Application Firewall) для блокировки подозрительных запросов, содержащих сигнатуры SQL-инъекций.
Если вы обнаружили в логах подобные конструкции, это сигнал о попытке взлома. Необходимо проверить уязвимые параметры, убедиться, что все запросы параметризованы, и при необходимости провести аудит безопасности.
Часто задаваемые вопросы
Является ли EXTRACTVALUE уязвимостью MySQL?
Сама по себе функция не является уязвимостью. Опасность возникает, когда разработчик позволяет пользовательским данным напрямую попадать в SQL-запрос без экранирования. EXTRACTVALUE лишь служит инструментом для эксплуатации.
Что означает 0x7e в этом выражении?
0x7e — шестнадцатеричное представление символа тильды ~. Он используется как разделитель, чтобы чётко выделить извлекаемое значение в тексте ошибки.
Почему используется 3913=3913?
Это всегда истинное условие. Оно нужно для того, чтобы ELT вернула первую строку (в данном случае 1). В реальной атаке вместо этого подставляются подзапросы, возвращающие нужные данные.
Таким образом, выражение AND EXTRACTVALUE(3913,CONCAT(0x7e,((SELECT (ELT(3913=3913,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции, демонстрирующий, как можно заставить MySQL вывести результат подзапроса в сообщении об ошибке. Понимание этой техники помогает специалистам по безопасности выявлять и предотвращать атаки на веб-приложения.
Комментарии
—Войдите, чтобы оставить комментарий