Что это за запрос?
Строка ' OR EXTRACTVALUE(5397,CONCAT(0x7e,((SELECT (ELT(5397=5397,1)))),0x7e))-- - — это типичный пример SQL-инъекции, основанной на ошибках (error-based SQL injection). Она использует функции MySQL EXTRACTVALUE, CONCAT и ELT, чтобы заставить базу данных вернуть данные в сообщении об ошибке. Такой подход часто применяется злоумышленниками для обхода аутентификации или извлечения информации из базы.
В этой статье мы детально разберём, как работает каждый элемент payload, почему используются шестнадцатеричные маркеры 0x7e и как защитить приложение от подобных атак.
Разбор payload по частям
1. Начало: ' OR ... -- -
Символ ' закрывает строковый литерал в уязвимом запросе. Затем следует OR — логический оператор, который делает условие всегда истинным, если правая часть верна. В конце -- - — комментарий, который обрезает оставшуюся часть оригинального SQL-запроса, чтобы синтаксис оставался корректным.
2. Функция EXTRACTVALUE
EXTRACTVALUE — встроенная функция MySQL (и MariaDB), предназначенная для извлечения значения из XML-документа по XPath-выражению. Она принимает два аргумента: XML-строку и путь XPath. Если XPath-выражение некорректно или возвращает не-скалярное значение, функция генерирует ошибку. Именно это свойство и используется в атаке: злоумышленник подставляет в XPath данные, которые нужно извлечь, и они попадают в текст ошибки.
В нашем payload первым аргументом передаётся число 5397 — это не XML, но MySQL автоматически преобразует его в строку. Второй аргумент — результат CONCAT.
3. CONCAT и маркеры 0x7e
CONCAT объединяет строки. Здесь он склеивает три части: символ 0x7e (тильда ~ в ASCII), результат подзапроса и ещё одну тильду. Тильды служат маркерами, по которым потом легко найти извлечённые данные в сообщении об ошибке. Например, ошибка может выглядеть так: XPATH syntax error: '~1~'. Всё, что между тильдами, — это результат внедрённого подзапроса.
4. Подзапрос (SELECT (ELT(5397=5397,1)))
ELT — функция MySQL, возвращающая N-й элемент из списка строк. Синтаксис: ELT(N, str1, str2, ...). В данном случае ELT(5397=5397,1) возвращает 1, потому что условие 5397=5397 истинно (равно 1). Если бы условие было ложным, ELT вернул бы NULL. Таким образом, подзапрос всегда возвращает строку '1'. Это простейшая демонстрация: в реальной атаке вместо 1 мог бы быть, например, результат (SELECT password FROM users LIMIT 1).
Конструкция SELECT (ELT(...)) без указания таблицы допустима в MySQL и возвращает скалярное значение.
5. Собираем всё вместе
Итоговое выражение для EXTRACTVALUE: CONCAT('~', (SELECT (ELT(5397=5397,1))), '~'). Оно вернёт строку '~1~'. Затем EXTRACTVALUE пытается интерпретировать эту строку как XPath-выражение. Строка ~1~ не является корректным XPath, поэтому MySQL выдаёт ошибку вида: XPATH syntax error: '~1~'. В этой ошибке злоумышленник видит результат выполнения подзапроса.
Зачем это нужно злоумышленнику?
Error-based инъекции позволяют извлекать данные из базы, даже если приложение не выводит результаты запроса напрямую. Сообщения об ошибках часто отображаются пользователю или попадают в логи, которые может прочитать атакующий. Используя функции вроде EXTRACTVALUE, можно побайтово вытащить содержимое таблиц: имена пользователей, пароли, номера кредитных карт и т.д.
Конкретно этот payload с ELT(5397=5397,1) — учебный пример. Он проверяет, что инъекция работает: если в ответе появляется ошибка с ~1~, значит, приложение уязвимо и можно двигаться дальше.
Как защититься от SQL-инъекций?
Основная причина успеха таких атак — недостаточная фильтрация пользовательского ввода и конкатенация строк при построении SQL-запросов. Вот ключевые меры защиты:
- Параметризованные запросы (prepared statements). Используйте их везде, где возможно. Они отделяют код от данных, и внедрение становится невозможным.
- Экранирование специальных символов. Если параметризация недоступна, применяйте функции экранирования (например,
mysqli_real_escape_stringв PHP). - Валидация и фильтрация ввода. Проверяйте типы данных, используйте белые списки там, где это уместно.
- Отключение подробных сообщений об ошибках. Не выводите ошибки базы данных пользователю; логируйте их отдельно.
- Использование ORM. Современные ORM-библиотеки обычно используют параметризацию по умолчанию.
- Регулярные аудиты безопасности. Проводите сканирование уязвимостей и пентесты.
Важно также ограничить права пользователя базы данных, от имени которого работает приложение: не давайте ему доступ к системным таблицам и лишним базам.
Заключение
Payload ' OR EXTRACTVALUE(5397,CONCAT(0x7e,((SELECT (ELT(5397=5397,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции в MySQL. Он использует особенности функций EXTRACTVALUE и CONCAT для вывода данных в сообщении об ошибке. Понимание механики таких атак помогает разработчикам и администраторам лучше защищать свои приложения. Главное правило: никогда не доверяйте пользовательскому вводу и всегда используйте параметризованные запросы.
Комментарии
—Войдите, чтобы оставить комментарий