Smartbi v8.5 代码审计

目录结构

在找源码的过程中,看到该系统使用了 Servlet 框架,理解 Servlet 框架对后续的代码理解有帮助

servlet

https://86263008.github.io/web2024/back/java/jsp/servlet/index.html

https://kirklin.github.io/PrivateNotes/Java%E5%85%A8%E5%A5%97/JavaWeb/Servlet/#_11

https://blog.csdn.net/yxmoar/article/details/109889006

历史漏洞:

未授权访问

Smartbi 身份认证绕过漏洞

https://www.freebuf.com/vuls/373015.html

网上的 身份认证/内置用户登陆 绕过的代码和v8.5版本的有一些区别,不过还是能跟踪到代码漏洞点

1、代码分析

E:\Smartbi\Tomcat\webapps\smartbi\WEB-INF\lib\smartbi-FreeQuery.jar!\smartbi\freequery\filter\CheckIsLoggedFilter.class

首先找到 CheckIsLoggedFilter.class 文件的 needToCheck() 方法,

20250801173411982

接下来找找 CheckIsLoggedFilter 是在哪里利用的?

找到在web.xml中有我们需要的路由 /vision/RMIServlet

看到的文章中都是先知道了 RMIServlet 这个路由,然后找到 CheckIsLoggedFilter

20250801175223846

20250801174751116

尝试访问 http://localhost:18080/smartbi/vision/RMIServlet

20250801174912101

POC:

主要结构:

内置用户(service),口令为0a;public、system可能不存在。

20250806083335304

20250801175555800

20250801175813702

使用hackbar也可以,

20250801180133641

之后访问 http://localhost:18080/smartbi/vision/

发现已经进入后台

20250801180228087

SQL注入(FileResource)

FileResource 是用于处理文件的 Servlet

20250802132757662

E:\Smartbi\Tomcat\webapps\smartbi\WEB-INF\lib\smartbi-FreeQuery.jar!\smartbi\freequery\fileresource\FileResourceServlet.class

20250802132840122

分析代码:

20250802133545296

没有对 resID 参数进行过滤直接使用 executeQuery() 拼接执行sql语句,造成sql注入

构造payload:

可以sqlmap跑一下:

20250802140622564

SQL注入(RMIServlet)

E:\Smartbi\Tomcat\webapps\smartbi\WEB-INF\lib\smartbi-FreeQuery.jar!\smartbi\freequery\repository\FileResourceDAO.class

20250805165508359

getFileResource方法接收参数 id ,直接拼接SQl语句查询 t_fileresource 表,没有对 id 进行过滤或者其他的安全措施,存在SQL注入风险

20250805181321541

getFileResource方法在URLLinkService中调用:

E:\Smartbi\Tomcat\webapps\smartbi\WEB-INF\lib\smartbi-FreeQuery.jar!\smartbi\freequery\client\urllink\URLLinkService.class

20250805181341517

漏洞复现:

20250805182305339

后台rce

E:\Smartbi\Tomcat\webapps\smartbi\WEB-INF\lib\smartbi-FreeQuery.jar!\smartbi\freequery\sync\SyncServlet.class

20250802145216052

此处的参数 dbType、dbServer、dbName等全部由用户输入,可控且无任何检验、过滤

E:\Smartbi\Tomcat\webapps\smartbi\WEB-INF\lib\smartbi-FreeQuery.jar!\smartbi\freequery\sync\SyncResources.class

E:\Smartbi\SmartbiUnionServer\plugin\SmartbiPrestoClickHouseJdbc\smartbiCommon.jar!\smartbi\util\DbUtil.class

跟进 translateDriverInfo

构造poc:

20250802165747255

tomcat 历史漏洞(实则没有)

确定 tomcat 版本为 Apache Tomcat Version 7.0.34

E:\Smartbi\Tomcat\RELEASE-NOTES

20250731181914395

1、AJP 导致的 RCE

CVE-2020-1938 :Apache Tomcat AJP 漏洞复现和分析

https://www.cnblogs.com/backlion/p/12870365.html

默认情况下,Apache Tomcat会开启AJP连接器,方便与其他Web服务器通过AJP协议进行交互.但Apache Tomcat在AJP协议的实现上存在漏洞,导致攻击者可以通过发送恶意的AJP请求,可以读取或者包含Web应用根目录下的任意文件,如果配合文件上传任意格式文件,将可能导致任意代码执行(RCE).该漏洞利用AJP服务端口实现攻击,未开启AJP服务对外不受漏洞影响(tomcat默认将AJP服务开启并绑定至0.0.0.0/0).

确认 18009 端口开放,且能够建立 TCP 连接:

Test-NetConnection -ComputerName 127.0.0.1 -Port 18009

20250731185501657

使用 Ghostcat 漏洞检测工具:

https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi

脚本成功建立了AJP协议连接返回了Tomcat 7.0.34的错误页面

20250731191051181

可能由于Smartbi对WEB-INF目录做了额外保护或者Tomcat配置了限制访问,并不能读取到文件

文件上传

文件位置:Tomcat/webapps/smartbi/vision/designer/imageimport.jsp

对上传的文件名、MIME类型无判断、不严谨,可伪造伪造文件类型上传成功,造成漏洞

漏洞复现:

路由:http://localhost:18080/smartbi/vision/designer/imageimport.jsp

需要配置页(http://localhost:18080/smartbi/vision/config.jsp)的登录密码,所以不能和未授权访问结合,属于后台漏洞

20250805160347015

poc:

20250805161922205

20250805162159129

20250805162430488

JDBC反序列化

JDBC反序列化学习

https://sp4zcmd.github.io/2021/09/21/JDBC%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E5%AD%A6%E4%B9%A0/

https://xz.aliyun.com/news/7754

https://www.cnblogs.com/Litsasuk/articles/18410624

https://wiki.wgpsec.org/knowledge/ctf/JDBC-Unserialize.html

关键条件:

  1. mysql-connector-java 的依赖版本为5.1.44,支持 autoDeserialize=true 参数,具备反序列化触发点

  2. 在 pom.xml 中 common-collections 版本为 3.2.1,存在cc反序列化利用链

  3. 存在方法调用反射机制 RMIServlet ,可远程调用任意类方法

20250806085001007

20250806125442264

20250806125519870

漏洞分析:

触发点:DataSourceService -> testConnection

E:\Smartbi\Tomcat\webapps\smartbi\WEB-INF\lib\smartbi-FreeQuery.jar!\smartbi\freequery\client\datasource\DataSourceService.class

攻击者向/vision/RMIServlet 发送如下 POST 请求:

通过类名和方法名反射调用,即:

className = DataSourceService

methodName = testConnection

params = [...] 是 JSON 数组字符串,传进去后被包装成 JSONArray 类型。

接着 params 调用下面的方法:

execute方法处理逻辑:将传入的 JSON 转为 IDataSource 对象,

再进入 DataSourceService.testConnection()

进入 MetaDataServiceImpl.testConnection():

进入 ConnectionPool.getConnection():进行数据池连接

此时服务器向远程的FakeMysql尝试连接,就会接收到FakeMysql返回的恶意序列化数据,

漏洞复现:

搭建 FakeMysql 服务器,用 Javachains 搭建,将 3308端口开启,监听的是本机IP地址的3308端口

20250806161415587

构造 K1链

20250806162032486

构造poc:

20250806162931145

总结:

  1. 根据依赖版本确定存在漏洞
  2. 根据依赖的敏感函数找入口点

前台JDBC反序列化

漏洞分析:

E:\Smartbi\Tomcat\webapps\smartbi\WEB-INF\lib\smartbi-FreeQuery.jar!\smartbi\freequery\sync\SyncServlet.class

跟进 synchronize

跟进 DbUtil.getConnection

漏洞点产生在 translateDriverInfo ,此处可以拼接恶意数据库

漏洞复现:

构造POC:

同样的,开启3308端口,搭建FakeMysql服务器,生成K1链

成功利用:

20250806181941863

JNDI注入

漏洞分析:

20250806192734078

漏洞复现:

POC:

20250806192146688

生成K1链:

ldap://[ip]:15089/bb4e07

20250806192251404

20250806191933929

这里因为端口的问题没有利用成功。报错LDAP服务器未响应

Windows 系统将 50389 端口作为排除范围,不允许程序(包括 Docker)绑定使用它。安装JavaChains 时将 -p 50389:50389 ^改成了 -p 15089:50389 ^,可能监听不到,

20250806190250099

使用dnslog

ldap://192.168.1.25:15089/b69569

20250806193947601

20250806194037543

收到DNSLOG记录,说明漏洞存在

参考文章:

CVE-2020-1938 :Apache Tomcat AJP 漏洞复现和分析

https://www.cnblogs.com/backlion/p/12870365.html

Smartbi 身份认证绕过漏洞

https://www.freebuf.com/vuls/373015.html

信息搜集相关:

https://ckcah.github.io/2020/05/01/googlehack/

https://94248.github.io/2023/07/25/%E4%BF%A1%E6%81%AF%E6%94%B6%E9%9B%86%E7%9B%B8%E5%85%B3/

servlet

https://86263008.github.io/web2024/back/java/jsp/servlet/index.html

https://kirklin.github.io/PrivateNotes/Java%E5%85%A8%E5%A5%97/JavaWeb/Servlet/#_11

https://blog.csdn.net/yxmoar/article/details/109889006

JDBC反序列化学习

https://sp4zcmd.github.io/2021/09/21/JDBC%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E5%AD%A6%E4%B9%A0/

https://xz.aliyun.com/news/7754

https://www.cnblogs.com/Litsasuk/articles/18410624

https://wiki.wgpsec.org/knowledge/ctf/JDBC-Unserialize.html

javachains使用

https://java-chains.vulhub.org/zh/

Windows 系统将 50389 端口作为排除范围,不允许程序(包括 Docker)绑定使用它。如果改端口可能有一些问题,还是尽量在Linux搭可以避免端口问题。

20250806200152925

访问 localhost:8011

20250806200418498

密码:docker logs java-chains | findstr password

20250806200413737