主要还是看killer那个 ctf,然后以前实战也没怎么认真去打(坑太多了)。这次正好学习一下。
com.alibaba.fastjson.parser.ParserConfig#checkAutoType(java.lang.String, java.lang.Class<?>, int)

主要就是检查@type 指定的类

然后在判断时候在在反序化的map、缓存的map中,然后判断是不是白名单。

要是获取到就判断这些。不是期望类直接就包type not match。基本高版本要是不指定期望类,这一步就g了

如果我们利用cmonsio写入文件后, 这里都会获取不到,不再缓存 不是白名单,且这个classloader为null

这个时候就会调用classloader去获取这个class的流

这里清楚可以看到是sun.misc.Launcher$AppClassLoader


他的classpath路径jre的lib,jre下的class(默认没有)和项目的lib目录。
我们要是写文件在docbase目录下, 使用这个classloader是加载不到的。

最后来到这里
若果他是白名单类、jsonType,期望类的话。就会调用TypeUtils.loadClass(typeName, this.defaultClassLoader, cacheClass),要是这个类是白名单或者jsonType就会进行缓存
com.alibaba.fastjson.util.TypeUtils#loadClass(java.lang.String, java.lang.ClassLoader, boolean)

来到这里,这个defaulrclassloder是null,所以这里都是加载不到我们写入到docbase的类。

最后会来到这里。使用当前线程的classloader来加载

可以看到是webappclassloader


这里可以清楚看到docbase的目录。也就是说写入到docbase下的类要用webappclassloader才能加载到。

根据cache标志位,是否加入缓存。这cache就是前面提到的


最后又再次判断。
这也是为什么我写入到docbase后,要使用
{
"@type":"java.lang.Exception",
"@type":"org.example.Exception"
}这种形式来加载,expectClassFlag这样为true,然后使用webappclassloaer加载。
再回到上面

如果我们获取到class的流,然后调用ClassReader读入,在字节信息中获取到jsonType信息,jsonType就会改为true。也就是完全可以写一个后门类,类打上@JSONType就行。

这样就能符合它的判断,jsontype标志位也变为true

最后加入缓存。这样1.2.83也能触发。
但是在cmonsio写文件下这种情况下没什么意义, 写docbase 继承期望类就能正常加载,不继承在过不了判断,无法使用webappclassload加载,也就获取不到类,写到jre/lib需要替换懒加载的jar包,毫无意义。
在1.2.83的情况下,类名结尾为Exception或Error会直接返回null。
这个时候只能在sun.misc.Launcher$AppClassLoade来加载,也就是在jre下找利用,就是最经典的写懒加载jar包替换。
一般以chaset.jar、nashorn.jar,dnsns.jar 为主。
需要结合目录穿越写文件写到jre/lib目录。

一般在源码写上然后编译,这样不影响正常功能。
为了方便复现。这里只打包一个类

改成83 手动替换jar



org.apache.commons.io.input.CharSequenceInputStream
在commons-io 2.0-2.1上是没有的, 以及在高低版本上字节信息不同。c/cs


所以这里我套娃了一下,用org.apache.commons.io.input.CharSequenceReader的是配,这样io在2.0-2.7上都能利用。
再就是在不同系统os上,类随机到构造方法不同,导致写不了二进制数据。

io低版本会在linux随到decoder这个构造,不给decoder赋值,在解码流就会包空异常,

能利用的就是utf8,写不了二机制,只能利用ascii jar写入。实战千万别用,要是没打下目录,lib替换了影响服务。

随到这个就正常对charset赋值可以二进制数据。其余都没什么好说的了。
不得不说,fastjson真是java安全绕不过的大山。为此我也加入到chains。支持1.2.68 ,1.2.75-1.2.80.
io 2.0-2.7写文件

在能写二进制的情况下直接选就行
不能写二进制的话,使用

进行上传你要写的文件。

然后根据情况选择payload。
https://su18.org/post/fastjson-1.2.68/
https://flowerwind.github.io/2025/02/28/%E5%88%86%E4%BA%AB%E4%B8%80%E6%AC%A1%E7%BB%84%E5%90%88%E6%BC%8F%E6%B4%9E%E6%8C%96%E6%8E%98%E6%8B%BF%E4%B8%8B%E7%9B%AE%E6%A0%87/
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。