本文首发于先知:https://xz.aliyun.com/t/6914

漏洞分析

FastJson1.2.24 RCE

在分析1.2.47的RCE之前先对FastJson1.2.24版本中的RCE进行一个简单的漏洞链分析,为在本篇文章后面1.2.47中漏洞的调用过程做个铺垫。在本文中的1.2.24的payload只研究针对类jdbcRowSetImpl的,因为针对templatesImpl的payload而言在高版本java中要开启Feature.SupportNonPublicField才能进行对非共有属性的反序列化处理,因此是存在一定的限制的。因此针对类jdbcRowSetImpl的payload更具有通用型一些。本中所示代码及jar包请见附件。

exp.java

Exploit.class

首先在本地用marshalsec起一个ldap服务,用rmi也可以,只需将datasourcename中的服务更改为rmi即可

本文中环境为jdk1.8.0,首先在parse处下一个断点然后运行exp.java,本来打算正向找到setvalue函数,可是fastjson扫描json字符串的过程及反序列化时处理jdbcrowsetimpl类处处理流程过于繁琐,中间不知道得跟进多少个F7,很容易让人没有耐心继续调试分析,遂这里直接关注漏洞的核心点,即我们在setDataSourceName处下断点

即此时将从我们payload中指定的DataSourceName中去加载工厂类

在setautoconnect函数中调用了connect()函数,跟进后此时就能看到熟悉的lookup函数啦,我们知道jndi注入攻击中从远程加载恶意工厂类即是我们控制了lookup的入口参数,即控制了远程工厂类的加载地址,即此处即为关键点,F7步入

此时getDataSourceName()的返回值也可以看到即为我们所指定的恶意工厂类地址


然后跟进lookup看看如何调用实例化,这里调用了getURLOrDefaultInitCtx(name).lookup()函数

此时就到了java的命名服务管理的类,此时调用getURLContext函数请求ldap,进一步在其中调用getURLObject来通过从远程的ldap服务获取Context对象

最终完成exploit.class类的实例化,也就是工厂类的实例化,熟悉的getObjectInstance(),此时就完成了反序列化,从而触发exploit里的构造函数


整个漏洞的函数调用栈如下图所示

以下是一些针对fastjson不同版本的payload,可以看到bypass其实在@type类的前面加上L或者[,这都是因为fastjson在处理域时会将扫描到的这些字符进行去除

FastJson1.2.47 RCE

漏洞影响版本:fastjson<1.2.51

exp.java

Exploit.class与1.2.24相同,在1.2.24以后fastjson默认关闭了反序列化任意类的操作,增加了checkautotype,也就是指定要用来反序列化的类不能够在一些黑名单中,从而做了一定的限制。此次漏洞利用的核心点是java.lang.class这个java的基础类,在fastjson 1.2.48以前的版本没有做该类做任何限制,加上代码的一些逻辑缺陷,造成黑名单以及autotype的绕过。我们仍然在parse处下断点,这里正向F7跟进到如下图所示

在DefaultJSONParser中,对json字符串进行扫描解析,此时解析到key值为a,接下来就对a中的字段进行解析,这里解析到@type以后,进而扫描到typename为java.lang.class,此时将调用parseconfig类的checkautotype函数来检测要反序列化的类。

接着在checkautotype函数中此时从mappings中或者deserializers.findClass()方法来获取反序列化对象的对应类

这里实际上在findClass函数中的this.bucktet中去找要反序列化的类,而在bucket变量中包含了大量的基础类


这里关键点在这几句代码,找到的类通过getName()函数调用后就能获得类的类名,然后将该类名与传入的要反序列化的类名比较,若相等,即找到,则直接返回该类,这里返回值为类类型。

接着回到IedentityHashMap的checkautotype函数中返回java.lang.class类

进一步回到com/alibaba/fastjson/parser/DefaultJSONParser.class中调用了对应的序列化处理类,也就是有了要反序列化的类,此时咋处理这类就是接下来的操作,获取的类为com.alibaba.fastjson.serializer.MiscCodec

接下来到364行即开始调用MiscCodec的deserialze函数

在其deserialze函数中可以看到其首先取得了我们payload字符串中var对应的值,也就是我们要利用的JdbcRowSetImpl类

接着对我们要反序列化的类进行一个类型判断,一直到303行,此时类满足判断,即java.lang.class为类类型的类,所以直接返回strVal,也就是恶意类

在TypeUtils类中可以看到此时loadclass函数的cache默认为true,这也是个重要的导致bypass的地方

那么这里首先loadclass尝试在mapping中取加载java.lang.class要引入的类,要是没有找到的话,此时将通过mapping.put方法将该类放到mapping中,那么不需要autotype就完成了对恶意类的加载

完成了对第一部分的json的字符串的解析已经成功加载了恶意类,因此此时json字符串继续向后扫描,扫描到b,此时处理b对应的值,当扫描到@type时继续调用checkautotype函数

那么因为之前我们已经通过java.lang.class的加载类的功能将jdbcrowsetimpl类加载到了mappings中,因此这里getclassfrommapping就能够返回我们的恶意类

接着又回到Defaultjsonparse类中

接着对于jdbcrowsetimpl类,调用fastjsonDeserialize_1_jdbcrowsetimpl类来对该类进行解析调用,那么接下来因为已经bypass了黑名单和autotype,因此之后rce的流程和1.2.24的一样了

还是回到熟悉的setAutoCommit函数,具体流程见上面1.2.24的描述,最终能够触发calc,此时用mashalsec打ldap一样是可以的

整个漏洞的函数调用栈如下图所示

漏洞修复

在1.2.48版本的补丁中,首先黑名单做了更新,其中就包含了java.lang.class这个类,并且MiscCodec中也将传入的cache参数置为了false,这样通过payload中a部分的java.lang.class引入JdbcRowSetImpl类,b部分通过
mappings获取JdbcRowSetImpl类的方法就失效了。

参考

https://www.anquanke.com/post/id/181874
https://www.kingkk.com/2019/07/Fastjson%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E-1-2-24-1-2-48/
https://saucer-man.com/information_security/346.html

一步一步学习FastJson1.2.47远程命令执行漏洞的更多相关文章

  1. Fastjson <= 1.2.47 远程命令执行漏洞

    一.漏洞利用过程 查看java版本:java -version jdk版本大1.8 openjdk versin "1.8.0_222" 下载漏洞利用文件:git clone ht ...

  2. Fastjson 1.2.47 远程命令执行漏洞复现

    前言 这个漏洞出来有一段时间了,有人一直复现不成功来问我,就自己复现了下,顺便简单记录下这个漏洞原理,以便后面回忆. 复现过程 网上已经有很多文章了,这里就不在写了.主要记录一下复现过程中遇到的问题 ...

  3. FastJson远程命令执行漏洞学习笔记

    FastJson远程命令执行漏洞学习笔记 Fastjson简介 fastjson用于将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean.fastjson.ja ...

  4. 【漏洞复现】Fastjson <=1.2.47远程命令执行

      0x01 漏洞概述 漏洞描述 Fastjson是一款开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBe ...

  5. Struct2远程命令执行漏洞(S2-053)复现学习

    1.S2-053(CVE-2017-12611) RCE出自一道题目 http://www.whalwl.cn:8027/hello.action 漏洞产生原因:Struts2在使用Freemarke ...

  6. Kali学习笔记30:身份认证与命令执行漏洞

    文章的格式也许不是很好看,也没有什么合理的顺序 完全是想到什么写一些什么,但各个方面都涵盖到了 能耐下心看的朋友欢迎一起学习,大牛和杠精们请绕道 实验环境: Kali机器:192.168.163.13 ...

  7. CVE-2017-6920 Drupal远程代码执行漏洞学习

     1.背景介绍: CVE-2017-6920是Drupal Core的YAML解析器处理不当所导致的一个远程代码执行漏洞,影响8.x的Drupal Core. Drupal介绍:Drupal 是一个由 ...

  8. PHP代码审计学习之命令执行漏洞挖掘及防御

    [1]可能存在命令执行漏洞的函数: 00x1:常用的命令执行函数:exec.system.shell_exec.passthru 00x2:常用的函数处理函数:call_user_func.call_ ...

  9. 代码审计之CVE-2017-6920 Drupal远程代码执行漏洞学习

     1.背景介绍: CVE-2017-6920是Drupal Core的YAML解析器处理不当所导致的一个远程代码执行漏洞,影响8.x的Drupal Core. Drupal介绍:Drupal 是一个由 ...

随机推荐

  1. 字体图标iconfont

    字体图标的作用: 1. 可以做出图片一样可以做的事情, 改变透明度, 旋转度,等... 2. 但是本质其实是文字,可以很随意的改变颜色, 产生阴影,透明效果等 3. 本身体积更小,但携带的信息并没有消 ...

  2. 对SPI进行参数化结构设计

    前言 为了避免每次SPI驱动重写,直接参数化,尽量一劳永逸. SPI master有啥用呢,你发现各种外围芯片的配置一般都是通过SPI配置的,只不过有3线和四线. SPI slave有啥用呢,当外部主 ...

  3. python3爬虫之requests库基本使用

    官方文档链接(中文) https://2.python-requests.org/zh_CN/latest/ requests  基于  urllib3 ,python编写. 安装 pip insta ...

  4. 自定义centos

    目录 自定义centos 1. 为什么要自定义centos 2. 自定义centos步骤 自定义centos 1. 为什么要自定义centos 在使用官网的 centos镜像,只有200m,很小,但是 ...

  5. liunx mkisofs 命令的使用(制作iso)

    参考的博客 http://www.cnblogs.com/darkknightzh/p/8564483.html 有很多时候需要在liunx 环境中将文件打成 iso 所有很多时候就会用到这个命令(m ...

  6. Sharing is only supported for boot loader classes because bootstrap classpath has been appended

    在idea里面运行项目,terminal里面报“Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boo ...

  7. Pandas-Numpy-Scipy-Matplotlib

    Ref:Using iloc, loc, & ix to select rows and columns in Pandas DataFrames 单纯的方括号只有两个用途:基于列的label ...

  8. Selenium(五)鼠标和键盘事件

    1.模拟鼠标找到大分类下的子分类.以网易严选为例. 如果直接找到  坚果炒货 这个元素,然后点击它来实现跳转,是会报错的. 模拟鼠标停留--点击行为:  页面已成功跳转 2.键盘事件 模拟搜索操作: ...

  9. SQL SERVER 查询第20行到30之间的数据

    1.先查询前20行的ID,后查询除去20条记录的前10条记录 SELECT TOP * FROM tbBank WHERE BankID NOT IN(SELECT TOP BankID FROM t ...

  10. linux实操_shell流程控制

    if判断: 基本语法: if [ 条件判断式 ] then 程序 elif [ 条件判断式 ] then 程序 fi 实例:请编写一个shell程序,如果输入的参数,大于60,则输出“及格了”,如果小 ...