Что это за строка?
Строка ) AND EXTRACTVALUE(8398,CONCAT(0x7e,((SELECT (ELT(8398=8398,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие payload'ы используются злоумышленниками для извлечения данных из базы через сообщения об ошибках, которые возвращает сервер.
Подобные конструкции часто встречаются в отчётах пентестеров, на тренировочных платформах (DVWA, SQLZoo) и в эксплойтах. Понимание того, как они устроены, помогает разработчикам и администраторам распознавать атаки и выстраивать защиту.
Разбор по элементам
Рассмотрим каждый компонент запроса.
- ) — закрывающая скобка. Она нужна, чтобы «закрыть» оригинальное выражение в уязвимом запросе и добавить собственное условие.
- AND — логический оператор, который позволяет присоединить дополнительное условие к исходному WHERE. Если исходное условие истинно, выполнится и наша инъекция.
- EXTRACTVALUE(8398, ...) — функция MySQL, извлекающая значение из XML-документа. В данном случае первый аргумент (8398) — это не XML, а число. Функция вызывается намеренно некорректно, чтобы спровоцировать ошибку, в текст которой попадёт результат второго аргумента.
- CONCAT(0x7e, ..., 0x7e) — объединение строк.
0x7e— шестнадцатеричный код символа~(тильда). Тильды служат маркерами, чтобы в сообщении об ошибке легко было найти внедрённые данные. - (SELECT (ELT(8398=8398,1))) — подзапрос.
ELT(N, str1, str2, ...)возвращает строку по номеру N. Выражение8398=8398всегда истинно (1), поэтому ELT возвращает первый аргумент — строку '1'. В реальной атаке вместо этого подзапроса подставляют вызовы, извлекающие версию СУБД, имя пользователя, таблицы и т.п. - -- - — комментарий. В MySQL символы
--начинают комментарий до конца строки, а пробел после них обязателен. Дефис в конце часто добавляют для надёжности, чтобы комментарий точно сработал.
В результате выполнения такого запроса MySQL выдаёт ошибку вида: XPATH syntax error: '~1~'. Именно эти тильды и содержимое между ними возвращаются атакующему.
Зачем это нужно злоумышленнику
Error-based инъекции применяются, когда приложение не выводит данные напрямую (например, при UNION-инъекции), но показывает сообщения об ошибках БД. С помощью EXTRACTVALUE, UPDATEXML или GEOMETRYCOLLECTION можно заставить сервер вернуть произвольные данные в тексте ошибки.
Пример из реальной практики: замена ELT(8398=8398,1) на version() или user() позволяет узнать версию MySQL и текущего пользователя. Далее можно извлекать имена таблиц и колонок через information_schema.
Пример работы
Допустим, уязвимый запрос выглядит так:
SELECT * FROM users WHERE id = '$id';
Если передать в $id значение 1) AND EXTRACTVALUE(8398,CONCAT(0x7e,version(),0x7e))-- -, итоговый запрос станет:
SELECT * FROM users WHERE id = '1) AND EXTRACTVALUE(8398,CONCAT(0x7e,version(),0x7e))-- -';
Сервер вернёт ошибку с версией MySQL, например: XPATH syntax error: '~8.0.32~'.
Как защититься
Основной способ защиты — использование параметризованных запросов (prepared statements). Они гарантируют, что пользовательский ввод не будет интерпретирован как SQL-код.
- Никогда не конкатенируйте ввод в SQL-строку.
- Используйте ORM и библиотеки с параметризацией.
- Отключите вывод подробных ошибок БД в production.
- Применяйте WAF как дополнительный слой.
- Проводите регулярные аудиты кода и пентесты.
Важно: даже если приложение не показывает ошибки, error-based инъекция может быть использована вслепую (blind), поэтому полагаться только на скрытие ошибок нельзя.
Вывод
Строка ) AND EXTRACTVALUE(8398,CONCAT(0x7e,((SELECT (ELT(8398=8398,1)))),0x7e))-- - — это учебный пример эксплуатации уязвимости SQL-инъекции в MySQL. Она демонстрирует, как с помощью функций EXTRACTVALUE, CONCAT и ELT можно извлечь данные через сообщения об ошибках. Знание таких конструкций помогает разработчикам лучше понимать риски и внедрять надёжную защиту.
Комментарии
—Войдите, чтобы оставить комментарий