Что это за строка?
Строка %"))) AND EXTRACTVALUE(5501,CONCAT(0x7e,((SELECT (ELT(5501=5501,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используются для извлечения данных из базы через принудительное формирование ошибки, текст которой содержит результат подзапроса. Подобные payload'ы часто встречаются в отчётах по безопасности и в учебных материалах по SQL-инъекциям.
Внешне строка выглядит как набор символов, но на самом деле это тщательно сконструированное выражение, которое при подстановке в уязвимый SQL-запрос заставляет сервер вернуть сообщение об ошибке с внедрёнными данными.
Разбор конструкции по частям
Давайте разберём каждый элемент, чтобы понять логику злоумышленника.
- %"))) — начальная часть, которая закрывает ранее открытые кавычки и скобки в оригинальном запросе. Обычно используется для «выхода» из строкового литерала и добавления собственного кода. Количество скобок и кавычек подбирается под конкретный запрос.
- AND — логический оператор, позволяющий присоединить условие к WHERE-части исходного запроса.
- EXTRACTVALUE(5501, CONCAT(...)) — вызов встроенной функции MySQL, которая извлекает значение из XML-документа. Если первый аргумент не является корректным XML, функция генерирует ошибку. Злоумышленник использует это для вывода данных в тексте ошибки.
- CONCAT(0x7e, ((SELECT (ELT(5501=5501,1)))), 0x7e) — конкатенация трёх частей: шестнадцатеричный код 0x7e (символ ~), результат подзапроса и снова ~. Символы ~ служат маркерами, по которым потом легко найти внедрённые данные в сообщении об ошибке.
- (SELECT (ELT(5501=5501,1))) — подзапрос, возвращающий значение. ELT() — функция, возвращающая N-й элемент из списка. В данном случае условие 5501=5501 всегда истинно, поэтому ELT возвращает первый элемент — число 1. Это простейшая проверка работоспособности инъекции. В реальной атаке вместо этого подзапроса мог бы быть, например, (SELECT password FROM users LIMIT 1).
- -- - — комментарий, который «отрезает» оставшуюся часть оригинального запроса, чтобы синтаксис оставался корректным.
Таким образом, вся конструкция заставляет MySQL выполнить EXTRACTVALUE с заведомо некорректным XML (из-за добавленных символов ~), что приводит к ошибке вида: XPATH syntax error: '~1~'. В этом сообщении и оказывается результат подзапроса.
Цель инъекции
Основная цель — получить возможность читать данные из базы, не имея прямого доступа. Error-based инъекции особенно удобны, когда приложение не выводит результаты запроса на экран, но отображает сообщения об ошибках базы данных. Злоумышленник может последовательно извлекать имена таблиц, колонок и содержимое записей, подставляя вместо ELT(5501=5501,1) другие подзапросы.
Например, чтобы узнать версию MySQL, можно использовать EXTRACTVALUE(1, CONCAT(0x7e, (SELECT version()), 0x7e)). В ответе придёт ошибка с версией. Аналогично извлекаются имена пользователей, хеши паролей и другие конфиденциальные сведения.
Почему используется EXTRACTVALUE?
Функция EXTRACTVALUE появилась в MySQL давно и часто применяется в error-based атаках, потому что она генерирует ошибку с контролируемым текстом. Другие функции, такие как UPDATEXML или GEOMETRYCOLLECTION, также могут использоваться для этих целей. Важно, что EXTRACTVALUE не требует прав на запись или специальных привилегий — достаточно возможности выполнять SELECT.
Символ 0x7e (~) выбран не случайно: он редко встречается в обычных данных, поэтому его легко найти в сообщении об ошибке и извлечь полезную нагрузку. Иногда вместо ~ используют другие разделители, например, 0x3a (двоеточие).
Как защититься от таких инъекций?
Лучший способ защиты — использовать параметризованные запросы (prepared statements). Они разделяют код SQL и данные, поэтому даже если в параметр попадёт строка с кавычками и функциями, она будет воспринята как обычное значение, а не как часть запроса. Также рекомендуется:
- Отключить вывод подробных ошибок базы данных на продакшн-серверах. Пользователь должен видеть общее сообщение, а детали писать в лог.
- Использовать ORM или библиотеки, которые автоматически экранируют опасные символы.
- Проводить регулярные аудиты кода и сканирование уязвимостей.
- Ограничить права пользователя базы данных, от имени которого работает приложение: только необходимые операции.
Важно понимать, что экранирование спецсимволов (например, добавление обратного слэша перед кавычкой) не всегда спасает, если оно выполнено неправильно. Параметризация — надёжнее.
Пример уязвимого запроса
Предположим, в приложении есть такой код на PHP:
$id = $_GET['id'];
$query = "SELECT * FROM products WHERE id = '$id'";
$result = mysqli_query($conn, $query);Если передать в параметр id строку %"))) AND EXTRACTVALUE(5501,CONCAT(0x7e,((SELECT (ELT(5501=5501,1)))),0x7e))-- -, то итоговый запрос примет вид:
SELECT * FROM products WHERE id = '%"))) AND EXTRACTVALUE(5501,CONCAT(0x7e,((SELECT (ELT(5501=5501,1)))),0x7e))-- -'После подстановки MySQL выполнит инъекцию и вернёт ошибку с внедрённым значением. Если приложение выводит эту ошибку, злоумышленник увидит результат.
Заключение
Рассмотренная строка — типичный пример error-based SQL-инъекции, использующей функцию EXTRACTVALUE для извлечения данных через сообщения об ошибках. Понимание таких конструкций необходимо специалистам по безопасности для тестирования приложений и разработчикам для предотвращения уязвимостей. Помните: лучшая защита — параметризованные запросы и скрытие деталей ошибок от конечных пользователей.
Комментарии
—Войдите, чтобы оставить комментарий