1.漏洞信息

1.1 漏洞简介

· 漏洞名称:Fastjson 1.2.24远程代码执行漏洞(com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl)

· 漏洞编号:无

· 漏洞类型:远程代码执行

· CVSS评分:无

· 漏洞危害等级:高危

1.2 组件概述

Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、

Android客户端等多种应用场景。下图是Fastjson组件中的反序列化流程。

1.3 漏洞概述

漏洞是利用fastjson autotype在处理json对象的时候,未对@type字段进行完全的安全性验证,攻击者可以传入危险类,奇热服务器接收到危险类执行其中恶意代码。攻击者通过这种方式可以实现远程代码执行漏洞的利用,获取服务器的敏感信息泄露,甚至可以利用此漏洞进一步对服务器数据进行修改,增加,删除等操作,对服务器造成巨大的影响。

1.4 漏洞利用条件

· 

1.5 漏洞影响

影响版本:
Fastjson < 1.2.25

1.6 漏洞修复

获取Fastjson最新版本,下载链接:https://github.com/alibaba/fastjson

2.漏洞复现

2.1 环境拓扑

2.2 应用协议

8080/HTTP

2.3 复现过程

基于Windows平台,使用环境目录下的fastjsondemo环境,拷贝后使用Idea打开fastjsondemo文件夹,下载maven资源,运行DemoApplication类,即可启动环境。效果如图。

运行sniper工具箱,填写表单信息,点击Attack,效果如图。

3.漏洞分析

3.1 技术背景

JavaBean:

JavaBean 是特殊的 Java 类,使用 Java 语言书写,并且遵守 JavaBean API 规范。JavaBean的特征:

· 提供一个默认的无参构造函数。

· 需要被序列化并且实现了 Serializable 接口。

· 可能有一系列可读写属性。

· 可能有一系列的 getter 或 setter 方法。

方法 描述
getPropertyName() 举例来说,如果属性的名称为 myName,那么这个方法的名字就要写成 getMyName() 来读取这个属性。这个方法也称为访问器。
setPropertyName() 举例来说,如果属性的名称为 myName,那么这个方法的名字就要写成 setMyName()来写入这个属性。这个方法也称为写入器。

程序实例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

public class StudentsBean implements java.io.Serializable

{

private String firstName = null;

private String lastName = null;

private int age = 0;

public StudentsBean() {

}

public String getFirstName(){

return firstName;

}

public String getLastName(){

return lastName;

}

public int getAge(){

return age;

}

public void setFirstName(String firstName){

this.firstName = firstName;

}

public void setLastName(String lastName){

this.lastName = lastName;

}

public void setAge(int age) {

this.age = age;

}

}

3.2 详细分析

3.2.1 代码分析

Fastjson通过parseObject方法解析传入的json数据。

调用DefaultJSONParser缺省方法对json格式数据进行解析。

在方法的参数中,调用ParserConfig.getGlobalInstance()方法获取ParserConfig类中的初始配置,其中黑名单(denyList)也在此类中进行配置。

调用addDeny方法循环添加denyList数组中的黑名单。

回到DefaultJSONParser方法,初始化结束后,调用JSONScanner方法对传入的json字符串设置读取位置,判断过程中处理Unicode字符集的BOM标识。

回到DefaultJSONParser方法,为token赋值。

回到JSON入口类,获取到DefaultJSONParser类型对象,调用parse()方法进行解析。

在parse方法中,通过判断lexer.token(),进入对应的代码块。

调用JSONObject构造方法,初始化JSONObject类中的map属性。

回到DefaultJSONParser#parse方法,调用parseObject方法,对传入的json数据进行字节读取。

一般会读取json字符串中的双引号进入scanSymbol方法中,在scanSymbol方法中计算字符串的hash。

调用addSymbol方法,将键名添加到SymbolTable中。

回到DefaultJSONParser#parseObject方法中,判断key值是否为@type。如果是,独步则进入if判断条件下的代码块中。

调用scanSymbol方法,以双引号作为quote变量值,进行@typejson字段值的value读取。

获得@type的键值,调用addSymbol方法,将@type的字段值添加到SymbolTable中。

回到DefaultJSONParser#parseObject方法中,调用TypeUtils.loadClass方法进行类加载操作。

进入loadClass方法中,首先会在现有的mappings中寻找从@type传入的classname。

如果在原有的mappings中没有记录传入的classname,则调用contextClassLoader.loadClass获取AppClassLoader类加载器,并加载到mappings中与@type传入的类进行关联,最后返回clazz对象。

回到DefaultJSONParser#parseObject方法中,调用this.config.getDeserializer(clazz)获取反序列化器。

进入getDeserializer方法中,首先现有的IdentityHashMap中进行hash匹配,如果无法匹配,则进入第二个if判断条件中重载getDeserializer方法,继续获取反序列化器。

在getDeserializer(Class方法中,首先依然会与现有的IdentityHashMap中进行hash匹配。如果无法匹配,会事先进行黑名单匹配,在调用ServiceLoader.load判断META-INF/services/下是否存在传入的classname类。

如果没有寻找到对应的类,则判断传入的classname是否是继承java.lang.Enum、是否是array类型选择对应的反序列化器生成方法。如果上述条件不满足,则继续判断传入的classname是否为Set、HashSet、Collection、List、ArrayList,如果不是则继续判断classname是否继承Collection,Map,Throwable接口。如果上述条件都不满足,则调用createJavaBeanDeserializer方法生成JavaBean反序列化器。

进入createJavaBeanDeserializer方法,判断asmEnable是否为true,调用JavaBeanInfo.build方法建立JavaBean。

建立JavaBean过程中,通过反射机制获取传入的class中所有的属性,方法,并保存在数组中。选择一个无参构造函数作为默认的构造函数。

循环遍历method数组中的方法,并从中选取符合条件的方法。(条件:同时满足方法名长度大于4;非静态方法;方法类型为Void。或者方法类型与方法所在类相同)

再从筛选的规则中继续筛选出形参数量为1的方法。

再从筛选出的方法中获取以set方法开头的方法,并检测JavaBean的方法命名规范,筛选出符合规范的方法。调用TypeUtils.getField方法获取与set方法对应的属性值。

进入getField方法中,遍历@type传入的class以及其父类的所有属性值,返回寻找到属性。

最终调用add方法,将获取的Field属性保存到fieldList列表中。

再以相同的流程筛选出存在get方法的属性值,如果筛选出的filed属性值不在fieldList,则添加到fieldList列表中。

调用JavaBeanInfo方法对JavaBeanInfo中的属性进行初始化,并返回实例化对象。

回到ParserConfig#createJavaBeanDeserializer方法中,获取到beanInfo对象,并从beaninfo中取出defaultConstructor默认构造器、field属性。

通过检测fieldClass属性值,为asmEnable标志位赋值

由于@type传入的class中的javabean方法,存在只读属性,因此asmEnable标志位变成false。

根据asmEnable标志位,进行if条件判断,调用JavaBeanDeserializer构造方法,并返回实例化对象。

在实例化过程中,会将beaninfo中的属性赋值给JavaBeanDeserializer类中的filed反序列化器。

回到ParserConfig#getDeserializer方法,调用putDeserializer方法,将生成的反序列化器与@type传入的class类进行关联,最后返回反序列化器

回到DefaultJSONParser#parseObject方法,调用deserializer.deserialze方法进行反序列化。

进入deserialze方法中,首先根据token值进入到对应的条件代码块。调用scanSymbol方法。

进入scanSymbol方法,对传入的json字符串进行解析,和解析@type的流程相同,解析传入的其他属性字段。

回到JavaBeanDeserializer#deserialze方法中,解析的属性值返回并赋值到key属性中。

调用parseField方法解析属性。

进入parseField方法,调用smartMatch方法,获取field反序列化器。

进入smartMatch方法,首先会从建立的javabean中寻找是否存在对应key中属性值的操作方法。

如果没有匹配到javabean中的方法,则先消除掉属性值中的_和-符号,再与javabean中的方法进行匹配,如果匹配成功,则返回反序列化器。如果匹配失败,则返回null。

回到parseField方法中,设置Feature.SupportNonPublicField状态,并根据状态值进入if条件判断的代码块中,生成extraFieldDeserializers扩展的反序列化器。再从反序列化器中取出从fastjson获取的json数据中指定的属性。

调用parseField方法,按照获取deserializer反序列化器的流程,获取fieldValueDeserilizer反序列化器。得到的fieldValueDeserilizer反序列化器,在parseField方法中调用deserialze方法进行反序列化。

由于传入的参数中存在数组,fastjson首先会调用getFastMatchToken方法,获取当前json字符串位置的token标志值。

由于json字符串中的数组是以[data]的形式传入的,所以当检测属性值是以[开头,则为token赋值为14。

由于是数组类型,因此在获取反序列化器时,会进入ObjectArrayCodec类进行解析。

调用ObjectArrayCodec#parseArray方法,进行数组的解析。

根据数组中的元素类型,进行token赋值,再依据token,选择对应token值,进入对应的if代码块。

解析数组中元素时,如果元素时String类型,则将字符串按照byte类型进行读取,在读取的过程中,会先进行base64解码。

最终以]符号作为数组结束符。

回到ObjectArrayCodec#deserialze方法中,调用toObjectArray方法,将传入的数组数据,转换成数组对象。

回到DefaultDeserializer#parseField方法中,调用setValue方法,将获取的数组对象,赋予到@type class中的对应属性中。

在解析最后一个_outputProperties参数时,会在setValue方法中进行反射,调用getOutputProperties方法。

此方法会在调用的过程中,实例化从bytecode传入恶意class文件,从而实现攻击。

3.2.2补丁分析

Fastjson1.2.25版本新增了checkAutoType方法,设置了autotype开关,对@type字段进行限制。如果autotype开关关闭,则无法从@type字段传入类进行jndi攻击。

增加了黑名单中的类,对fastjson的gadget进行拦截。

4.参考链接

1.https://www.runoob.com/jsp/jsp-javabean.html
2.http://xxlegend.com/2018/10/23/%E5%9F%BA%E4%BA%8EJdbcRowSetImpl%E7%9A%84Fastjson%20RCE%20PoC%E6%9E%84%E9%80%A0%E4%B8%8E%E5%88%86%E6%9E%90/
3.https://github.com/alibaba/fastjson/compare/1.2.24...1.2.25

Fastjson 1.2.24远程代码执行漏洞(com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl)相关推荐

  1. commons-pool2-2.3 jar包_[漏洞复现]FastJson 1.2.61远程代码执行漏洞(From第三方jar包)

    前言 最近FastJson更新了黑名单,升级到了1.2.61版本,我尝试bypass其黑名单,在AutType打开的情况下成功绕过了黑名单防护.(目前暂未修复,官方即将更新) 复现环境准备 1.JDK ...

  2. fastjson远程代码执行漏洞问题分析

    背景 fastjson远程代码执行安全漏洞(以下简称RCE漏洞),最早是官方在2017年3月份发出的声明, security_update_20170315 没错,强如阿里这样的公司也会有漏洞.代码是 ...

  3. Apache Log4j2远程代码执行漏洞攻击,华为云安全支持检测拦截

    近日,华为云安全团队关注到Apache Log4j2 的远程代码执行最新漏洞.Apache Log4j2是一款业界广泛使用的基于Java的日志工具,该组件使用范围广泛,利用门槛低,漏洞危害极大.华为云 ...

  4. Apache Log4j 远程代码执行漏洞直接让安全圈过年~

    在此声明:本文章的目的是让大家参考此漏洞的修复方法切记不要批量刷SRC,否则后果自负与本人无关, 安全圈直接过年了 苹果 百度 shiro从2014年-2022年坚持到了现在,log4j是下一个能养活 ...

  5. 开源高性能 RISC-V 处理器“香山”国际亮相;Apache Log4j 远程代码执行漏洞;DeepMind 拥有 2800 亿参数的模型 | 开源日报

    整理 | 宋彤彤 责编 | 郑丽媛 开源吞噬世界的趋势下,借助开源软件,基于开源协议,任何人都可以得到项目的源代码,加以学习.修改,甚至是重新分发.关注「开源日报」,一文速览国内外今日的开源大事件吧! ...

  6. Apache Log4j2远程代码执行漏洞风险紧急通告,腾讯安全支持全面检测拦截

    腾讯安全注意到,一个Apache Log4j2的高危漏洞细节被公开,攻击者利用漏洞可以远程执行代码. 漏洞描述: 腾讯安全注意到,一个Apache Log4j2反序列化远程代码执行漏洞细节已被公开,L ...

  7. android fastjson漏洞_【漏洞预警】Fastjson 远程代码执行漏洞(暂无PoC)

    Fastjson简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库.它采用一种"假定有序快速匹配"的算法,把JSON Parse的性能提升到极致,是目前Jav ...

  8. fastjson反序列化漏洞_【安全风险通告】fastjson反序列化远程代码执行漏洞安全风险通告...

    近日,奇安信CERT监测到fastjson官方发布新版本,修补了一个反序列化远程代码执行漏洞.远程攻击者可利用该漏洞绕过autoType限制,进而可在目标服务器上执行任意命令.鉴于该漏洞影响较大,建议 ...

  9. php 使用fastjson,Fastjson caucho-quercus远程代码执行漏洞

    Fastjson 组件介绍 Fastjson 是一个 Java 语言编写的高性能功能完善的 JSON 库.它采用一种 " 假定有序快速匹配 " 的算法,把 JSON Parse 的 ...

最新文章

  1. 【微读书】《人工智能颠覆未来战争》连载之一:机器战胜人类?——AlphaGo人机对战的启示...
  2. 详细程序注解学OpenCL一 环境配置和入门程序
  3. ASP编程常用的15个非常有用的代码及用法
  4. 程序间数据共享与传递(1):EXPORT/IMPORT、SAP/ABAP Memory
  5. ARMA模型的性质之方法性工具
  6. Excel的一点小事
  7. 股债轮动策略之行业版
  8. 安装ISA2004后,加入域时提示:远程过程调用失败且未运行的解决办法
  9. Android 热补丁之 Tinker 原理解析
  10. android 浏览器抓包工具下载,WebSee app下载-WebSee抓包工具v1.2.1 安卓版-腾牛安卓网...
  11. Word另存为PDF时,将目录转换为PDF书签
  12. 芯片——摩尔定律的传奇(下)
  13. windows 配置永久路由
  14. 驾考一点通维语版_【驾考宝典下载】2020官方最新_电脑版手机版维语版 - 驾考宝典...
  15. 头插法和尾插法的详细区别
  16. 论文管理工具:Zotero使用心得
  17. 主DNS、辅助DNS、缓存DNS和基于CDN的利用DNS服务器实现负载均衡
  18. k8s中文件描述符与线程限制
  19. Python-数据库游标对象详解
  20. vue Bus的使用

热门文章

  1. EMQ X 插件持久化系列 (五)MySQL MQTT 数据存储
  2. 耶鲁大学《博弈论》课程——纳什均衡
  3. 福建师范大学 “挑战杯”校赛金银奖分析文档
  4. 万能遥控程序c语言,单片机解码万能红外遥控器的C51程序
  5. C语言的除法运算:整除/和求余%
  6. 虚拟机字符界面大小调整
  7. 机器人中的数值优化|【一】数值优化基础
  8. Linux操作系统--文本编辑器(保姆级教程)
  9. 领域驱动设计系列文章(1)——通过现实例子显示领域驱动设计的威力
  10. 基于HI600的低成本最小RTK系统详细搭建过程