Что это за строка?
Строка %')) AND EXTRACTVALUE(4419,CONCAT(0x7e,((SELECT (ELT(4419=4419,1)))),0x7e))-- - представляет собой классический пример error-based SQL-инъекции (инъекции на основе ошибок) для СУБД MySQL. Такие конструкции используются для получения данных из базы через вывод сообщений об ошибках. В данном случае строка содержит функции EXTRACTVALUE, CONCAT и ELT, а также комментарий -- -, который обрезает остаток исходного запроса.
Подобные строки часто встречаются в отчётах пентестеров, в материалах по безопасности и в учебных заданиях (например, на платформах DVWA или SQLZoo). Они демонстрируют, как злоумышленник может извлечь информацию из базы данных, если веб-приложение не фильтрует пользовательский ввод.
Разбор компонентов инъекции
Давайте посмотрим, из чего состоит эта строка и как она работает.
1. %')) — закрытие исходного запроса
Символы %' и )) предназначены для того, чтобы «закрыть» предыдущие части SQL-запроса, которые формируются в уязвимом приложении. Например, если исходный запрос выглядит так:
SELECT * FROM users WHERE name = '%' AND password = '...'
то вставка %')) может привести к преждевременному закрытию строкового литерала и скобок, после чего добавляется новый оператор AND с полезной нагрузкой.
2. AND EXTRACTVALUE(4419, CONCAT(0x7e, ...)) — вызов функции с ошибкой
Функция EXTRACTVALUE(XML_document, XPath_expression) в MySQL предназначена для извлечения значения из XML-документа по XPath-выражению. Если XPath-выражение некорректно, MySQL генерирует ошибку, в тексте которой может содержаться переданное значение. Это и есть основа error-based инъекции.
В нашем случае первым аргументом передаётся число 4419 (произвольный идентификатор), а вторым — результат CONCAT(0x7e, ((SELECT (ELT(4419=4419,1)))), 0x7e). Символ 0x7e — это тильда (~), которая используется как разделитель, чтобы облегчить поиск вывода в сообщении об ошибке.
3. ELT(4419=4419, 1) — генерация полезной нагрузки
Функция ELT(N, str1, str2, ...) возвращает строку с номером N из списка. В данном случае 4419=4419 — это логическое выражение, которое всегда истинно (1). Таким образом, ELT(1, 1) возвращает '1'. Это простейшая демонстрация: в реальной атаке вместо 1 мог бы быть подзапрос, извлекающий имя пользователя или хеш пароля.
Например, вместо ELT(4419=4419,1) злоумышленник мог бы использовать ELT(4419=4419, (SELECT password FROM users LIMIT 1)), и тогда в ошибке отобразился бы пароль.
4. -- - — комментарий
Последовательность -- (с пробелом после) в MySQL означает начало комментария, который продолжается до конца строки. Это позволяет «отбросить» оставшуюся часть оригинального запроса, чтобы синтаксис стал корректным.
Как работает атака целиком
Предположим, уязвимый код формирует запрос так:
$query = "SELECT * FROM items WHERE category = '" . $_GET['cat'] . "'";
Если передать строку %')) AND EXTRACTVALUE(4419,CONCAT(0x7e,((SELECT (ELT(4419=4419,1)))),0x7e))-- -, то итоговый запрос примет вид:
SELECT * FROM items WHERE category = '%')) AND EXTRACTVALUE(4419,CONCAT(0x7e,((SELECT (ELT(4419=4419,1)))),0x7e))-- -'
После закрытия кавычки и скобок (хотя в данном примере скобки могут быть лишними, они часто используются для обхода фильтров) добавляется условие AND EXTRACTVALUE(...). При выполнении MySQL попытается вычислить EXTRACTVALUE и сгенерирует ошибку, так как второй аргумент не является корректным XPath. В тексте ошибки появится что-то вроде:
XPATH syntax error: '~1~'
Таким образом, атакующий видит результат выполнения вложенного запроса (в нашем случае — просто число 1).
Зачем это нужно злоумышленнику?
Error-based инъекции позволяют извлекать данные посимвольно или целыми строками, если приложение выводит сообщения об ошибках базы данных на страницу. Это один из самых быстрых способов получить информацию о структуре БД и её содержимом. В отличие от blind-инъекций, где нужно задавать много вопросов, здесь достаточно одного запроса, чтобы увидеть результат.
Однако для успешной эксплуатации необходимо, чтобы сервер возвращал подробные ошибки. В production-окружениях часто отключают вывод ошибок, что снижает риск.
Как защититься от таких инъекций?
- Используйте параметризованные запросы (prepared statements). Это самый надёжный способ: данные передаются отдельно от SQL-кода, и внедрение становится невозможным.
- Экранируйте специальные символы. Если по каким-то причинам нельзя использовать подготовленные выражения, применяйте функции экранирования (например,
mysqli_real_escape_stringв PHP). - Отключите вывод ошибок БД в production. Сообщения об ошибках должны логироваться, но не отображаться пользователю.
- Ограничьте права пользователя БД. Не давайте приложению прав на чтение системных таблиц или выполнение опасных функций.
- Регулярно проводите аудит безопасности. Используйте сканеры уязвимостей и пентесты.
Пример легального использования EXTRACTVALUE
Функция EXTRACTVALUE сама по себе не является вредоносной. Она применяется для работы с XML-данными в MySQL. Например:
SELECT EXTRACTVALUE('<root><user>admin</user></root>', '/root/user');
Вернёт admin. Опасность возникает только тогда, когда пользовательский ввод попадает в SQL-запрос без должной обработки.
Заключение
Строка %')) AND EXTRACTVALUE(4419,CONCAT(0x7e,((SELECT (ELT(4419=4419,1)))),0x7e))-- - — это учебный пример error-based SQL-инъекции для MySQL. Она демонстрирует, как злоумышленник может использовать функции EXTRACTVALUE и CONCAT для вывода данных через сообщения об ошибках. Понимание таких техник необходимо для разработки безопасных приложений и защиты от атак. Если вы встретили подобную строку в логах или запросах, это признак попытки взлома, и следует немедленно проверить безопасность вашего кода.
Комментарии
—Войдите, чтобы оставить комментарий