首页 > 其他分享 >Fastjson反序列化漏洞

Fastjson反序列化漏洞

时间:2023-01-08 23:56:05浏览次数:44  
标签:Fastjson 调用 漏洞 JSON getter 序列化 方法 setter

前言

Fastjson 是阿里开发的一个 Java 库,用于将 Java 对象序列化为 JSON 格式,也可将字符串反序列化为 Java 对象。

Fastjson 是非常多见的 Java 反序列化漏洞,CTF中也出现的非常频繁。

Fastjson 1.2.24

Fastjson 1.2.24 版本的反序列化漏洞在 2017年 首次爆出,之后更是难以平息。

Fastjson 序列化对象的方法主要是toJSONString 方法,而反序列化还原对象的方法有3个

parseObject(String text)
parse(String text)
parseObject(Srting text, Class\clazz)

在序列化和反序列化的过程中会自动去调用反序列化对象中的 getter、setter方法以及构造函数,这就是 Fastjson 反序列化漏洞产生的原因,接下来我们来具体来看一下。

探究前的准备

首先我们先在pom.xml导入fastjson 1.2.24

image-20220311201052216

接下来我们定义如下的类来进行测试:

image-20220329192807025

属性 getter setter
public String t1
private int t2
private boolean t3
private Map t4
private Map t5

探究序列化的过程

JSON.toJSONString(String)

image-20220329193004607

在序列化字符串的时候,会调用类中所有的getter方法,我们发现最后产生的序列化字符串和平时见的有些不一样。

其实我们只需要在该方法中加入参数SerializerFeature.WriteClassName方法,传入SerializerFeature.WriteClassName可以使得Fastjson支持自省,开启自省后序列化成JSON的数据就会多一个@type,这个是代表对象类型的JSON文本。FastJson的漏洞就是他的这一个功能去产生的,在对该JSON数据进行反序列化的时候,会去调用指定类中对于的get/set/is方法。

探究反序列化过程

JSON.parse(jsonstr)

按照之前序列化的情况类比推理一下,猜测被调用的方法应该是setT1、setT2和setT5(因为T3和T4没有setter方法),然后我们执行一下该方法,看看是不是和想象中的一样

image-20220329194547129

很明显,我们的猜测也不是全无道理,只不过为什么在反序列化的过程中调用了getT4呢!我们先保留这个问题继续往下看!

JSON.parseObject(jsonstr, FastjsonTest.class)

这次我们直接执行该方法,发现它和上一个方法的结果一样!

image-20220329194734629

通过上网查阅资料,需要满足下面的条件时,getter方法就会被调用

  1. 这个getter方法不存在setter方法
  2. 返回值类型继承自Collection || Map || AtomicBoolean || AtomicInteger ||AtomicLong

上边这俩个原因是主要原因,这也就是为什么只调用了getT4而没有调用getT3,其他调用条件应该算是gettersetter方法的必须条件

方法名需要长于4
非静态方法
以 get 字符串开头,且第四个字符需要是大写字母
方法不能有参数
方法为 public 属性

JSON.parseObject(jsonstr)

我们再来看看最后一个方法,竟然执行了这么多

image-20220329194853076

仔细看一看,其实不难发现,调用的前四个方法和之前那俩个一样,然后接着调用了所有的getter方法,所以也就不难理解了

反序列化后的类型

我们再查看三种反序列化方法的返回类型

image-20220329195206035

我们通过调试查看了这三种方法返回的类型,发现JSON.parseObject(jsonstr)方法还真是独特,分析得知:

parseObject(String text)其实就是执行了parse(),随后将返回的Java对象通过JSON.toJSON()转为JSONObject对象

总结

JSON.parse(jsonstr) JSON.parseObject(jsonstr, FastjsonTest.class) JSON.parseObject(jsonstr)
T1 setter setter setter getter
T2 setter setter setter getter
T3 getter
T4 getter getter getter getter
T5 setter setter getter

上述为测试结果,下边为属性的类型和有无getter/setter

属性 getter setter
public String t1
private int t2
private boolean t3
private Map t4
private Map t5
  1. 反序列化过程中会调用所有的setter方法
  2. 如果没有setter方法,会调用满足条件的getter方法
方法名需要长于4
非静态方法
以 get 字符串开头,且第四个字符需要是大写字母
方法不能有参数
返回值类型继承自Collection \|\| Map \|\| AtomicBoolean \|\| AtomicInteger \|\|AtomicLong
getter 方法对应的属性只能有 getter 不能有setter方法
方法为 public 属性

happyFastjson

可以很容易的找到fastjson反序列化的入口

image-20220312171609724

发现FlagBean类中可以读取到flag

image-20220312171800310

于是构造payload

poc={
    "a":{
        "@type":"com.ctfshow.happyfjs.Beans.FlagBean",
        "flag":{
            "@type":"java.util.HashMap"
    	}
    }
}

该payload现实经过JSON.parse(poc)调用了所有setter方法

  1. 这里没有setFlag方法,并且满足其他执行getFlag的条件,所以执行了getFlag方法
  2. 序列化字符串中没有free属性,所以不执行setFree方法

此时因为this.count=1所以并没有执行系统命令,然后这里又对返回的对象进行了toString方法,通过调试发现,实际上这里还是调用了toJSONString方法

image-20220330141042688

所以相当于再次进行了序列化操作,所以会执行所有的getter方法,然后就会输出flag

这里我尝试将poc修改为如下:

poc={
    "@type":"com.ctfshow.happyfjs.Beans.FlagBean",
    "flag":{
        "@type":"java.util.HashMap"
    }
}

通过调试发现调用的是一下方法

image-20220330142006231

这个方法是类对象的默认toString方法,我们可以通过覆写来实现新的toString方法

标签:Fastjson,调用,漏洞,JSON,getter,序列化,方法,setter
From: https://www.cnblogs.com/seizer/p/17035786.html

相关文章

  • ThinkPHP v5.0.24 反序列化
    ThinkPHPv5.0.24反序列化前言昨天花了一下午的时间才把反序列化链给审明白,今天记录一下笔记再来审一遍。(自己还是太菜了~~~)在我的印象中,ThinkPHP框架的漏洞非常多,所以......
  • Nginx的alias指令引发的漏洞
    前言一开始看到alias都不知道是什么,我们先来学习一下Nginx以其高性能著称,常用作前端反向代理服务器。同时nginx也是一个高性能的静态文件服务器。通常都会把应用的静态文......
  • Apache Log4j2 RCE漏洞复现
    看我看我,有没有大佬悄咪咪的给我个exp打自己过过瘾漏洞描述ApacheLog4j2是一个基于Java的日志记录工具。该工具重写了Log4j框架,并且引入了大量丰富的特性。该日......
  • XXE漏洞
    XXE漏洞的学习XXE:XMLExternalEntity即外部实体,从安全角度理解成XMLExternalEntityattack外部实体注入攻击(那为啥不叫XEE)。对于XXE想要真正的了解它,就需要先来了......
  • Phar反序列化漏洞
    前言通常我们在利用反序列化漏洞的时候,只能将序列化后的字符串传入unserialize(),随着代码安全性越来越高,利用难度也越来越大。但是利用phar文件会以反序列化的形式存......
  • Flask框架及其漏洞学习
    Flask是什么?Flask是一个相对于Django而言轻量级的Web框架,是Python开发的一个基于Werkzeug和Jinja2的web开发微框架,它的优势是极其简洁,但又非常灵活,而且容易学习和应用。......
  • Struts2系列漏洞复现汇总-持续更新中
    Struts2漏洞目录struts2漏洞S2-001(CVE-2007-4556)(已完成)struts2漏洞S2-003(已完成)struts2漏洞S2-005(已完成)struts2漏洞s2-007(已完成)struts2漏洞S2-008......
  • 中间件漏洞——ngnix
    文件解析漏洞由php配置不当产生的漏洞,与nginx版本无关php.ini文件中的cgi.fix_pathinfo的值为1时,fastcgi不认识用户上传的畸形文件会修复路径再由php-fpm.conf中的secur......
  • Redis未授权访问漏洞复现
    redis数据库默认无密码认证,当数据库未设置认证时,即存在未授权漏洞,可以导致服务器被远控等危害。复现使用客户端连接redis远程服务器./redis-cli-h127.0.0.1-p6379......
  • Go 自定义序列化
    实现MarshalJSON()([]byte,error)方法,序列化后可以把原来的枚举数转化为枚举数对应的字符串实现UnmarshalJSON([]byte)error方法,可以把byte中的枚举的字符串转化为对......