Что такое SQL-инъекция через EXTRACTVALUE?
Запрос ') AND EXTRACTVALUE(3425,CONCAT(0x7e,((SELECT (ELT(3425=3425,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции в СУБД MySQL. Злоумышленник использует функцию EXTRACTVALUE для того, чтобы заставить базу данных выдать сообщение об ошибке, содержащее результат выполнения вложенного запроса. Это позволяет извлекать произвольные данные (имена таблиц, колонок, пароли) путём анализа текста ошибок.
В данной статье мы детально разберём каждый элемент этой конструкции, объясним, как она работает, и расскажем, как защитить веб-приложение от подобных атак.
Разбор конструкции по частям
Начнём с синтаксического анализа. Запрос состоит из нескольких логических блоков:
')— закрывающая кавычка и скобка, которые завершают предыдущее выражение в уязвимом SQL-запросе. Это позволяет внедрить собственный код.AND— логический оператор, присоединяющий наше условие к оригинальному запросу.EXTRACTVALUE(3425,CONCAT(0x7e,((SELECT (ELT(3425=3425,1)))),0x7e))— вызов функции, генерирующей ошибку.-- -— комментарий, который игнорирует оставшуюся часть оригинального запроса.
Функция EXTRACTVALUE
EXTRACTVALUE(XML_fragment, XPath_expression) — это встроенная функция MySQL, предназначенная для извлечения значения из XML-документа по заданному XPath-выражению. Однако при передаче некорректного XPath-выражения она вызывает ошибку XPATH syntax error, в тексте которой отображается переданный аргумент. Именно это свойство и эксплуатируется.
Первый аргумент 3425 — произвольное число, которое в данном случае не играет роли, так как оно не является корректным XML. Ошибка возникнет уже на этапе разбора второго аргумента.
Функция CONCAT и шестнадцатеричные литералы
CONCAT(0x7e, ((SELECT (ELT(3425=3425,1)))), 0x7e) объединяет три строки. 0x7e — это шестнадцатеричное представление символа тильды ~. Тильды используются как маркеры начала и конца извлекаемых данных, чтобы облегчить их поиск в сообщении об ошибке.
В центре находится подзапрос SELECT (ELT(3425=3425,1)), который мы рассмотрим далее.
Функция ELT и условие 3425=3425
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В нашем случае ELT(3425=3425, 1) — первый аргумент является логическим выражением, которое всегда истинно (3425 действительно равно 3425), поэтому возвращается 1 (истина приводится к числу 1). Таким образом, подзапрос вернёт строку '1'.
В реальной атаке вместо 3425=3425 могло бы стоять условие, проверяющее, например, первый символ имени базы данных. Но в данном примере показан базовый шаблон, который всегда возвращает 1.
Как работает эксплуатация
Когда MySQL выполняет функцию EXTRACTVALUE с аргументом, содержащим символы, недопустимые в XPath (например, тильду ~), он генерирует ошибку вида:
ERROR 1105 (HY000): XPATH syntax error: '~1~'
В тексте ошибки мы видим ~1~ — это результат выполнения подзапроса, обёрнутый тильдами. Злоумышленник может подставить вместо 1 любой другой SQL-запрос, например, (SELECT version()), и получить версию СУБД в сообщении об ошибке.
Таким образом, error-based инъекция позволяет извлекать данные посимвольно или целыми строками, если они помещаются в сообщение об ошибке.
Пошаговый пример атаки
- Злоумышленник находит параметр, уязвимый для SQL-инъекции, например,
id=1'. - Внедряет конструкцию
') AND EXTRACTVALUE(3425,CONCAT(0x7e,(SELECT version()),0x7e))-- -. - Сервер возвращает ошибку:
XPATH syntax error: '~5.7.23-0ubuntu0.16.04.1~'. - Получив версию, атакующий может продолжить извлечение имён таблиц, колонок и данных.
Меры защиты
Чтобы предотвратить подобные атаки, необходимо применять комплексный подход:
- Использование подготовленных выражений (prepared statements). Это самый надёжный способ, при котором данные передаются отдельно от SQL-кода и не могут изменить структуру запроса.
- Экранирование специальных символов. Если подготовленные выражения недоступны, следует тщательно экранировать все пользовательские данные, попадающие в SQL-запрос.
- Ограничение прав пользователя БД. Приложение должно работать под учётной записью с минимально необходимыми привилегиями, чтобы даже при успешной инъекции ущерб был ограничен.
- Отключение вывода ошибок на продакшене. Сообщения об ошибках не должны показываться пользователям, чтобы не давать подсказок атакующему.
- Использование WAF (Web Application Firewall). Современные WAF могут обнаруживать и блокировать попытки SQL-инъекций по сигнатурам.
Заключение
Конструкция ') AND EXTRACTVALUE(3425,CONCAT(0x7e,((SELECT (ELT(3425=3425,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции, демонстрирующий, как небрежная обработка пользовательского ввода может привести к утечке данных. Понимание механизмов таких атак помогает разработчикам писать более безопасный код и своевременно закрывать уязвимости.
Комментарии
—Войдите, чтобы оставить комментарий