Что это за строка?
Строка `) AND EXTRACTVALUE(9615,CONCAT(0x7e,((SELECT (ELT(9615=9615,1)))),0x7e))-- - — это классический пример error-based SQL-инъекции для СУБД MySQL. Она предназначена для извлечения данных из базы через вывод сообщения об ошибке. Подобные конструкции часто встречаются в отчётах об уязвимостях и в логах веб-серверов, когда злоумышленник пытается проэксплуатировать недостаточную фильтрацию пользовательского ввода.
В этой статье мы разберём каждый элемент запроса, объясним, как работает функция EXTRACTVALUE, зачем нужны CONCAT и 0x7e, что делает ELT, и почему комментарий -- - завершает строку. Также рассмотрим, как защититься от подобных атак.
Разбор по частям
1. Начало: `) AND ...
Символы `)` (закрывающая скобка и обратный апостроф) часто используются для завершения оригинального SQL-запроса, который был вставлен в уязвимый параметр. Обратный апостроф в MySQL экранирует идентификаторы (имена таблиц, столбцов), а закрывающая скобка завершает выражение. После этого добавляется AND — логический оператор, который позволяет присоединить дополнительное условие к исходному запросу. Если исходный запрос был, например, SELECT * FROM users WHERE id = '...', то внедрение `) AND ... может изменить логику.
2. Функция EXTRACTVALUE
EXTRACTVALUE(XML_frag, XPath_expr) — это встроенная функция MySQL (до версии 8.0), которая извлекает значение из фрагмента XML с помощью выражения XPath. Если XPath-выражение некорректно или не соответствует XML-структуре, функция генерирует ошибку. Злоумышленники используют это для вывода данных: они передают в качестве XPath-выражения результат подзапроса, и если этот результат содержит недопустимые символы, MySQL выдаёт сообщение об ошибке, в котором отображается переданное значение. Таким образом, атакующий может прочитать содержимое базы данных.
В нашем случае первый аргумент — 9615 (произвольное число, которое не является корректным XML), а второй — CONCAT(0x7e, ((SELECT (ELT(9615=9615,1)))), 0x7e).
3. CONCAT и 0x7e
CONCAT объединяет строки. 0x7e — это шестнадцатеричное представление символа ~ (тильда). Тильда часто используется как маркер, чтобы отделить выводимые данные от остального текста ошибки. В результате выполнения CONCAT(0x7e, ..., 0x7e) получается строка, начинающаяся и заканчивающаяся тильдой, например ~1~.
4. Подзапрос с ELT
ELT(N, str1, str2, ...) возвращает N-ю строку из списка. В нашем случае ELT(9615=9615, 1) — условие 9615=9615 всегда истинно, поэтому ELT вернёт первый элемент, то есть 1. Это простейший пример, демонстрирующий технику. В реальной атаке вместо 1 мог бы быть, например, SELECT password FROM users LIMIT 1, и тогда ошибка содержала бы пароль.
5. Комментарий -- -
Последовательность -- (два дефиса) в MySQL начинает комментарий до конца строки. Пробел после дефисов обязателен, иначе комментарий не распознается. Добавленный дефис в -- - часто используется для обхода фильтров, которые могут удалять пробелы. Всё, что идёт после -- -, игнорируется базой данных. Это позволяет отсечь остаток оригинального запроса, который мог бы помешать выполнению внедрённого кода.
Как это работает в реальной атаке
Предположим, на сайте есть скрипт, который выполняет запрос:
SELECT * FROM articles WHERE id = '$_GET[id]'
Злоумышленник передаёт параметр id со значением:
1') AND EXTRACTVALUE(9615,CONCAT(0x7e,((SELECT (ELT(9615=9615,1)))),0x7e))-- -
Тогда итоговый запрос становится:
SELECT * FROM articles WHERE id = '1') AND EXTRACTVALUE(9615,CONCAT(0x7e,((SELECT (ELT(9615=9615,1)))),0x7e))-- -'
MySQL выполняет запрос, и при вычислении EXTRACTVALUE возникает ошибка, потому что первый аргумент 9615 не является корректным XML. В сообщении об ошибке будет отображено значение, переданное во втором аргументе, то есть ~1~. Если вместо ELT(9615=9615,1) подставить подзапрос, возвращающий конфиденциальные данные, они попадут в текст ошибки и будут видны атакующему.
Зачем это нужно злоумышленнику?
- Извлечение данных: error-based инъекции позволяют получать содержимое базы данных по частям, даже если прямой вывод результатов запроса не отображается на странице.
- Обход фильтров: использование функций вроде
EXTRACTVALUEиCONCATпомогает обойти простые сигнатуры WAF. - Автоматизация: существуют инструменты (sqlmap), которые автоматически подставляют подобные конструкции для дампа базы.
Как защититься?
Основной способ защиты от SQL-инъекций — использование подготовленных выражений (prepared statements) с параметризацией. Никогда не подставляйте пользовательский ввод напрямую в SQL-запрос. Также рекомендуется:
- Применять ORM или библиотеки, которые автоматически экранируют данные.
- Ограничить права пользователя базы данных, чтобы даже при успешной инъекции ущерб был минимален.
- Использовать WAF для фильтрации подозрительных запросов, но помнить, что WAF не является панацеей.
- Регулярно обновлять MySQL: в версии 8.0 функции
EXTRACTVALUEиUPDATEXMLбыли удалены, что снижает риск error-based атак.
Заключение
Строка `) AND EXTRACTVALUE(9615,CONCAT(0x7e,((SELECT (ELT(9615=9615,1)))),0x7e))-- - — это типичный пример error-based SQL-инъекции, эксплуатирующей функцию EXTRACTVALUE в MySQL. Понимание механики таких атак помогает разработчикам и специалистам по безопасности лучше защищать свои приложения. Если вы встретили подобную строку в логах, это признак попытки взлома, и следует немедленно проверить безопасность вашего кода.
Комментарии
—Войдите, чтобы оставить комментарий