首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >java安全最严厉的父亲-fastjson 高版本利用

java安全最严厉的父亲-fastjson 高版本利用

原创
作者头像
亿人安全
发布2026-01-23 16:25:45
发布2026-01-23 16:25:45
2660
举报
文章被收录于专栏:红蓝对抗红蓝对抗

原文首发在:奇安信攻防社区

链接:https://forum.butian.net/share/4715

fastjson 写文件

0x01 简介

主要还是看killer那个 ctf,然后以前实战也没怎么认真去打(坑太多了)。这次正好学习一下。

0x02 fastjson 加载

com.alibaba.fastjson.parser.ParserConfig#checkAutoType(java.lang.String, java.lang.Class<?>, int)

image.png
image.png

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

image.png
image.png

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

image.png
image.png

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

0x03 写class后fastjson 加载机制(docbase)

image.png
image.png

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

image.png
image.png

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

image.png
image.png

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

image.png
image.png
image.png
image.png

他的classpath路径jre的lib,jre下的class(默认没有)和项目的lib目录。

我们要是写文件在docbase目录下, 使用这个classloader是加载不到的。

image.png
image.png

最后来到这里

若果他是白名单类、jsonType,期望类的话。就会调用TypeUtils.loadClass(typeName, this.defaultClassLoader, cacheClass),要是这个类是白名单或者jsonType就会进行缓存

com.alibaba.fastjson.util.TypeUtils#loadClass(java.lang.String, java.lang.ClassLoader, boolean)

image.png
image.png

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

image.png
image.png

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

image.png
image.png

可以看到是webappclassloader

image.png
image.png
image.png
image.png

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

image.png
image.png

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

image.png
image.png
image.png
image.png

最后又再次判断。

这也是为什么我写入到docbase后,要使用

代码语言:javascript
复制
{
"@type":"java.lang.Exception",
"@type":"org.example.Exception"
}

这种形式来加载,expectClassFlag这样为true,然后使用webappclassloaer加载。

0x04 fastjson 1.x 全版本饶过

再回到上面

image.png
image.png

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

image.png
image.png

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

image.png
image.png

最后加入缓存。这样1.2.83也能触发。

但是在cmonsio写文件下这种情况下没什么意义, 写docbase 继承期望类就能正常加载,不继承在过不了判断,无法使用webappclassload加载,也就获取不到类,写到jre/lib需要替换懒加载的jar包,毫无意义。

0x05 1.2.83 fastjson利用

在1.2.83的情况下,类名结尾为Exception或Error会直接返回null。

这个时候只能在sun.misc.Launcher$AppClassLoade来加载,也就是在jre下找利用,就是最经典的写懒加载jar包替换。

一般以chaset.jar、nashorn.jar,dnsns.jar 为主。

需要结合目录穿越写文件写到jre/lib目录。

image.png
image.png

一般在源码写上然后编译,这样不影响正常功能。

为了方便复现。这里只打包一个类

image.png
image.png

改成83 手动替换jar

image.png
image.png
image.png
image.png
image.png
image.png

0x06 commonsio 优化

org.apache.commons.io.input.CharSequenceInputStream

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

image.png
image.png
image.png
image.png

所以这里我套娃了一下,用org.apache.commons.io.input.CharSequenceReader的是配,这样io在2.0-2.7上都能利用。

再就是在不同系统os上,类随机到构造方法不同,导致写不了二进制数据。

image.png
image.png

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

image.png
image.png

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

image.png
image.png

随到这个就正常对charset赋值可以二进制数据。其余都没什么好说的了。

0x07 加入chains

不得不说,fastjson真是java安全绕不过的大山。为此我也加入到chains。支持1.2.68 ,1.2.75-1.2.80.

io 2.0-2.7写文件

image.png
image.png

在能写二进制的情况下直接选就行

不能写二进制的话,使用

image.png
image.png

进行上传你要写的文件。

image.png
image.png

然后根据情况选择payload。

rerference

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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原文首发在:奇安信攻防社区
  • 链接:https://forum.butian.net/share/4715
  • fastjson 写文件
  • 0x01 简介
  • 0x02 fastjson 加载
  • 0x03 写class后fastjson 加载机制(docbase)
  • 0x04 fastjson 1.x 全版本饶过
  • 0x05 1.2.83 fastjson利用
  • 0x06 commonsio 优化
  • 0x07 加入chains
  • rerference
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档