简介
现实环境中可能会遇到fastjson不出网的情况,下面打两个不出网的靶场[1]。
fastjson1.2.47结合c3p0绕waf,不出网环境
这个环境比较特殊,docker起的两台机器,构造的机器不出网环境。
还是一样,首先就是探测具体版本。
1 | {"@type":"java.lang.AutoCloseable" |

版本1.2.47。这个漏洞爆出版本为1.2.47,在这个版本及以下fastjosn存在mappings缓存通杀绕过,利用的方式为JNDI,但不要忘了JNDI的利用是有一定条件的:
1、一般需要出网环境。
2、受到JDK版本限制,JDK8u191后受到trusturlcodebase限制远程加载,但也有绕过方法。
这里因为机器不出网,JNDI注入并不太适合,所以需要找其他方法。
因此下一步探测存在的依赖。利用Character转换报错可以判断存在何种依赖。
1 | { |
报错如下,RequestMapping本身为SpringBoot下的类,当存在该类时会报出类型转换错误,说明为SpringBoot项目。

否则无显示。

因此,通过这种方法结合已知的fastjson利用链POC所需的依赖类,最终探测服务中存在C3P0依赖(com.mchange.v2.c3p0.DataSources)。

fastjson本身结合c3p0有很多利用方式,其中提到最多的是不出网利用,hex base二次反序列化打内存马。在c3p0+fastjson利用其他文章中介绍的是需要依赖像cc链这样的反序列化链,但其实是不需要的,因为fastjson全版本都存在原生反序列化漏洞[2],且是通过TemplatesImpl加载类,很适合打内存马。
不出网打普通内存马
先找一个普通的内存马:Tomcat的Filter型内存马[3],但是直接引用是不行的,在c3p0二次反序列化环境中,如果针对不出网机器,需要使用的是TemplatesImpl这条链加载恶意字节码。但是对于使用TemplatesImpl,需要在恶意类中继承AbstractTranslet,并重写他的两个方法,否则该类无法被加载。更改后的内存马如下:Fain.java,要编译为class文件。就是在原来代码的基础上extends AbstractTranslet,然后重写AbstractTranslet的transform,在下面代码的最后,是重写的两个方法。
1 | import com.sun.org.apache.xalan.internal.xsltc.DOM; |
依赖如下:
1 | <dependency> |
之后就是关于C3P0二次反序列这条链,细节就不说了,与之前唯一个区别是之前使用的CC6那条反序列化链,但是其实fastjson全版本都存在类似CC这样的原生反序列化链漏洞,就不在需要对方环境中存在CC这样的依赖。 最终exp如下:
1 | import com.alibaba.fastjson.JSONArray; |
运行Test.java,运行的结果如下:
1 | { |
被拦截了,尝试发现是过滤了userOverridesAsString,尝试unicode、hex编码绕过依然不行,代码中过滤了\u,\x等编码前缀。

参考Y4tacker的文章[4],还可以添加_或+关键字绕过。

成了。测试一下内存马是否打成功。

不出网打冰蝎内存马
冰蝎内存马和普通的内存马一样,就是在这个冰蝎内存马的基础上[5],再实现extends AbstractTranslet,然后重写AbstractTranslet的transform。
代码RcememShell.java如下:
1 | import com.sun.org.apache.xalan.internal.xsltc.DOM; |
将其编译为RcememShell.class文件,然后同样修改一下Test.java中的路径。
获取到的结果为:
1 | { |
然后和普通马一样的绕过。然后使用冰蝎连接,密码为:goautomne。

fastjson1.2.68不出网的writefile漏洞
第一步,老样子,探测fastjson的版本1.2.68

要想写文件就要看后端使用了哪些依赖了。不是jdk11。

继续探测。org.springframework.web.bind.annotation.RequestMapping存在,是springboot。

继续探测。发现org.apache.commons.io.Charsets存在,根据FastJson漏洞学习[6],有文件读取的可能性了。

再继续探测。发现想去使用jdbc打反序列化,相关依赖都不存在,这个也是不行的。
1 | com.mysql.jdbc.Buffer //mysql-jdbc-5 |

试一试读文件,发现是可行的。
1 | { |

既然读文件可以了,那么尝试去进行写文件,看看可不可行。
- 写入jsp文件
- 写入计划任务反弹shell
- 写入
charsets.jar加载jar包 - 写入
class类加载
这几种方法的详细利用可参考[8:1]。
是springboot,第一个写入jsp文件,直接pass了。不出网环境,写入计划任务肯定也是不行的。写入charsets.jar加载jar包,对于这个方法charsets.jar加载只能加载一次,也就是说如果服务本身就调动过该jar包就不奏效[8:2],限制太强了。
那么就是最后一个写入class类加载了,试一试去实现。
文件读取列目录
现在的问题是,写入的class类的真实路径是什么?这里就用到文件读取,使用文件读取去列目录,找真实路径。
1 | import requests |
读取file:///usr/lib/jvm/,查看真实路径为java-1.8.0-openjdk-1.8.0.412.b08-1.el7_9.aarch64。

再去读路径,发现了file:///usr/lib/jvm/java-1.8.0-openjdk-1.8.0.412.b08-1.el7_9.aarch64/

再继续读路径file:///usr/lib/jvm/java-1.8.0-openjdk-1.8.0.412.b08-1.el7_9.aarch64/jre/

这里是发现存在classes目录,有时候是不存在的。不存在的时候就去创建一个classes目录。
创建classes目录
针对不存在的classes目录,这里因为我的环境中已经存在了这个目录,我就创建一个testclasses目录去演示目录的创建。
构造数据包如下,换一个创建的目录的地址。
1 | { |

再去列一下目录,发现成功创建了testclasses文件夹。

编写class类
对于不出网的环境,最好的方式就是打内存马了。
首先生成冰蝎内存马

对应的MemShell.java的文件为:
1 | import java.io.IOException; |
然后编译获取MemShell.class。并将MemShell.class转换为raw zlib流,方便后续文件的写入。
我使用的是mac os,要安装brew install qpdf,然后执行下面的命令:
1 | cat MemShell.class | zlib-flate -compress | base64 -w 0 |
Linux可以直接:
1 | cat MemShell.class | openssl zlib | base64 -w 0 |

然后就是将生成的base64的class文件进行写入,构造数据包如下:
1 | { |
文件成功写入。


触发class类的加载
需要使用java.lang.AutoCloseable来绕过autotype的检查进行后续类加载的触发。
对于没有写入的class类,如下:

对于写入的class类,进行触发,如下:
1 | { |

冰蝎连接/dddd,密码:Lhwdxjqwcrl,header头别忘记了Referer: Hrzpqa,自己生成的内存马。我因为header头忘记了,搞了半天没连上,以为什么原因呢😭,细心细心还是要细心。

成功实现。
参考
https://github.com/lemono0/FastJsonParty/blob/main/1247-waf-c3p0/write-up.md ↩︎
https://y4tacker.github.io/2023/04/26/year/2023/4/FastJson与原生反序列化-二/ ↩︎
https://github.com/Getshell/Mshell/blob/main/03-内存马实战/01-Tomcat/filter/89FRain.java ↩︎
https://y4tacker.github.io/2022/03/30/year/2022/3/浅谈Fastjson绕waf/ ↩︎
https://github.com/Getshell/Mshell/blob/main/03-内存马实战/01-Tomcat/filter/89IFRain.java ↩︎
https://x2nn.github.io/2025/10/24/FastJson漏洞学习/#fastjson1-2-68的readfile利用 ↩︎
https://yanghaoi.github.io/2024/08/18/fastjson-lou-dong-chang-jian-wa-jue-he-li-yong-fang-fa/#toc-heading-40 ↩︎
https://github.com/lemono0/FastJsonParty/blob/main/FastJson1268写文件RCE探究.md ↩︎ ↩︎ ↩︎