一步一步学习FastJson1.2.47远程命令执行漏洞
本文首发于先知: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远程命令执行漏洞的更多相关文章
- Fastjson <= 1.2.47 远程命令执行漏洞
一.漏洞利用过程 查看java版本:java -version jdk版本大1.8 openjdk versin "1.8.0_222" 下载漏洞利用文件:git clone ht ...
- Fastjson 1.2.47 远程命令执行漏洞复现
前言 这个漏洞出来有一段时间了,有人一直复现不成功来问我,就自己复现了下,顺便简单记录下这个漏洞原理,以便后面回忆. 复现过程 网上已经有很多文章了,这里就不在写了.主要记录一下复现过程中遇到的问题 ...
- FastJson远程命令执行漏洞学习笔记
FastJson远程命令执行漏洞学习笔记 Fastjson简介 fastjson用于将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean.fastjson.ja ...
- 【漏洞复现】Fastjson <=1.2.47远程命令执行
0x01 漏洞概述 漏洞描述 Fastjson是一款开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBe ...
- Struct2远程命令执行漏洞(S2-053)复现学习
1.S2-053(CVE-2017-12611) RCE出自一道题目 http://www.whalwl.cn:8027/hello.action 漏洞产生原因:Struts2在使用Freemarke ...
- Kali学习笔记30:身份认证与命令执行漏洞
文章的格式也许不是很好看,也没有什么合理的顺序 完全是想到什么写一些什么,但各个方面都涵盖到了 能耐下心看的朋友欢迎一起学习,大牛和杠精们请绕道 实验环境: Kali机器:192.168.163.13 ...
- CVE-2017-6920 Drupal远程代码执行漏洞学习
1.背景介绍: CVE-2017-6920是Drupal Core的YAML解析器处理不当所导致的一个远程代码执行漏洞,影响8.x的Drupal Core. Drupal介绍:Drupal 是一个由 ...
- PHP代码审计学习之命令执行漏洞挖掘及防御
[1]可能存在命令执行漏洞的函数: 00x1:常用的命令执行函数:exec.system.shell_exec.passthru 00x2:常用的函数处理函数:call_user_func.call_ ...
- 代码审计之CVE-2017-6920 Drupal远程代码执行漏洞学习
1.背景介绍: CVE-2017-6920是Drupal Core的YAML解析器处理不当所导致的一个远程代码执行漏洞,影响8.x的Drupal Core. Drupal介绍:Drupal 是一个由 ...
随机推荐
- QTabWidget标签实现双击关闭(转)
重载了QTabWidget(由于tabBar()是protected),这样就可以获取到标签了. 1 class Tab : public QTabWidget 2 { 3 Q_OBJECT 4 pu ...
- 补充:Python安装
需要安装Python2.7.Numpy和Matplotlib.由于Python不支持向下兼容,因此在Python3.×下你一定能正常运行Python2.×的代码.上述模块最简单的安装方法就是用软件包安 ...
- 【导出导入】IMPDP table_exists_action 参数的应用
转自:https://yq.aliyun.com/articles/29337 当使用IMPDP完成数据库导入时,如遇到表已存在时,Oracle提供给我们如下四种处理方式:a.忽略(SKIP,默认行为 ...
- Ubuntu下双显示器设定
自8.10后的版本,系统自带了xrandr工具,可以很好的实现双显示器.配置与使用如下: 介绍 X Windows 中有一个显示分辨率的概念,在默认情况下,这个显示分辨率为 max*max ,m ...
- 【ASE高级软件工程】第二次结对作业
重现baseline 我们选择重现CODEnn模型(论文:Deep Code Search),因为它结构简单.端到端可训练,且相比其它方法拥有较高的性能. Baseline原理 为了根据给定的quer ...
- flask 中的ORM ( 二 )
1 关系映射 1 多对多 1 什么是多对多 A表中的一条数据可以与B表中任意多条数据相关联 B表中的一条数据可以与A表中任意多条数据相关联 2 实现 在数据库中使用第三张表(关联表) 在编程语言中,可 ...
- Python学习记录8-继承2
继承 单继承和多继承 单继承:每个类只能继承一个类 多继承:每个类允许继承多个类 >>> class A(): pass >>> class B(A): pass ...
- Linux高级网络设置——给网卡绑定多个IP
假设这样一种场景: 某运营商的Linux服务器上装配了2家互联网公司的Web服务,每个Web服务分配了一个公网IP地址.但是运营商的Linux服务器只有一块网卡.这就需要在一块网卡上绑定多个IP地址. ...
- c多线程不加锁demo
// // Created by gxf on 2019/12/13. // #include <stdio.h> #include <stdlib.h> #include & ...
- win10 专业版永久密钥
激活码/密匙: 1.专业版: W269N-WFGWX-YVC9B-4J6C9-T83GXMH37W-N47XK-V7XM9-C7227-GCQG92X7P3-NGJTH-Q9TJF-8XDP9-T83 ...