问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
活动
摸鱼办
搜索
登录
注册
java安全最严厉的父亲-fastjson 高版本利用
渗透测试
fastjson 写文件
### 0x01 简介 主要还是看killer那个 ctf,然后以前实战也没怎么认真去打(坑太多了)。这次正好学习一下。 ### 0x02 fastjson 加载 com.alibaba.fastjson.parser.ParserConfig#checkAutoType(java.lang.String, java.lang.Class<?>, int)  主要就是检查@type 指定的类  然后在判断时候在在反序化的map、缓存的map中,然后判断是不是白名单。  要是获取到就判断这些。不是期望类直接就包type not match。基本高版本要是不指定期望类,这一步就g了 ### 0x03 写class后fastjson 加载机制(docbase)  如果我们利用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后,要使用 ```http { "@type":"java.lang.Exception", "@type":"org.example.Exception" } ``` 这种形式来加载,expectClassFlag这样为true,然后使用webappclassloaer加载。 ### 0x04 fastjson 1.x 全版本饶过 再回到上面  如果我们获取到class的流,然后调用ClassReader读入,在字节信息中获取到jsonType信息,jsonType就会改为true。也就是完全可以写一个后门类,类打上@JSONType就行。  这样就能符合它的判断,jsontype标志位也变为true  最后加入缓存。这样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目录。  一般在源码写上然后编译,这样不影响正常功能。 为了方便复现。这里只打包一个类  改成83 手动替换jar    ### 0x06 commonsio 优化 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赋值可以二进制数据。其余都没什么好说的了。 ### 0x07 加入chains 不得不说,fastjson真是java安全绕不过的大山。为此我也加入到chains。支持1.2.68 ,1.2.75-1.2.80. io 2.0-2.7写文件  在能写二进制的情况下直接选就行 不能写二进制的话,使用  进行上传你要写的文件。  然后根据情况选择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/>
发表于 2026-01-13 09:00:00
阅读 ( 492 )
分类:
漏洞分析
0 推荐
收藏
0 条评论
请先
登录
后评论
Unam4
4 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!