对ysoserial工具及java反序列化的一个阶段性理解【未完成】
经过一段时间的琢磨与反思,以及重读了大量之前看不懂的反序列化文章,目前为止算是对java反序列化这块有了一个阶段性的小理解。
目前为止,发送的所有java反序列化的漏洞中。主要需要两个触发条件:
1、反序列化的攻击入口
2、反序列化的pop攻击链
这两个条件缺一不可。网上大量分析gadgets的文章方法,让人误以为有攻击链就可以反序列化。其实这块是有一定的误导性的。在我最初研究反序列化的时候,我觉得攻击链是最重要的。其实不然,反序列化的攻击入口才是至关重要的。因为现阶段的java环境加上java所在的金融、保险等大型项目中,往往组件jar包和jdk版本是更新最缓慢的,因为这块需要测试大量的兼容性,对大型java项目来说,攻击链基本上一定存在,除非该java程序最近才被开发、部署,且开发人员喜欢用最新的版本软件包。
0X01攻击入口
目前其实在白盒过程中要比较快的查找攻击入口的话。可以全局搜索是否有以下这类方法函数:
ObjectInputStream.readObject
ObjectInputStream.readUnshared
XMLDecoder.readObject
Yaml.load
XStream.fromXML
ObjectMapper.readValue
JSON.parseObject
通过搜到到这些函数方法所在位置,再反向追踪是否可控输入流,如果可控,那么恭喜,反序列化的第一步已经完成。
拿我前几篇的文章来讲,XMLDecoder.readObject这块函数其实可以当做入口来看,至于为啥可以执行命令,你就当他当做system()函数来看,如果要更加深层的知道为啥可以执行命令,就可以跟下去,不过跟下去的话,属于更加底层的研究。
我们做安全其实可以分好几个攻击层次。
1、攻击普通开发者(这里的普通开发者可以指敏捷开发人员,大部分使用框架,或者现有函数库来使用,极大的加快了开发速度,但是对于框架具体底层功能实现可能不会特意去了解,大部分通过开发手册和api接口即可了解表层意义上的功能实现)
2、框架、底层库开发者(这类开发人员往往开发不是为了某个特定的东西,往往是为了帮助大量普通开发者更快、更短的代码实现一个功能,减少普通开发者的代码量,降低程序开发门槛)
3、系统层函数开发者(这类的开发者衔接的是高级面向对象的语言与底层汇编,甚至指令集之间的库函数)
随着攻击层次的加高,我们的攻击范围也会越广。
在这三个层次里,往往攻击入口点在1和2都会出现,更多的是出现在1层,而gadget在1和2也会出现,但是往往出现更多的在2层。
拿weblogic的xml反序列化来讲,把oracle的开发人员当做普通的拿现有开源框架库基础上开发的人员来看的话,他们造成反序列化的攻击入口点就在1层面,序列化的gadget在2层面。
在cve-2019-2725中,_async目录下的其实就是一个攻击入口,因为攻击入口和wls-wsat相似,所以后续分析和10271很像。
但是由于有10271补丁在,所以在2725中需要利用未在黑名单里的标签来绕过补丁。
0X02POP攻击链
java的pop攻击链不是说寻找难度不大,而是在现有yso工具在的情况下,对已有的漏洞利用来说,已经方便了很多。但是寻找一个新的pop链还是很困难的。
CommonsCollections1的gadget来说吧,因为网上这个的分析文章最多,所以也是我了解的比较熟悉的一个gadget。
这个漏洞的最关键地方是org.apache.commons.collections.functors.InvokerTransformer类下面的transform函数
public Object transform(Object input) {
if (input == null) {
return null;
} else {
try {
Class cls = input.getClass();
Method method = cls.getMethod(this.iMethodName, this.iParamTypes);
return method.invoke(input, this.iArgs);
} catch (NoSuchMethodException var5) {
throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' does not exist");
} catch (IllegalAccessException var6) {
throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' cannot be accessed");
} catch (InvocationTargetException var7) {
throw new FunctorException("InvokerTransformer: The method '" + this.iMethodName + "' on '" + input.getClass() + "' threw an exception", var7);
}
}
}
然后更关键的地方是
Class cls = input.getClass(); Method method = cls.getMethod(this.iMethodName, this.iParamTypes); return method.invoke(input, this.iArgs);
为啥这块危险呢,首先这个地方利用了java的反射机制,如果你不了解,你可以直接死记硬背或者理解成这样子写就是有一定问题的,等同于system(xxx),而xxx根据transform的形参来看,也就是input是我们可控的。且之间没有任何过滤。
this.iMethodName, this.iParamTypes
public InvokerTransformer(String methodName, Class[] paramTypes, Object[] args) {
this.iMethodName = methodName;
this.iParamTypes = paramTypes;
this.iArgs = args;
}
这两个读一下InvokerTransformer类的实现代码,发现初始化InvokerTransformer的时候,这两个也可控。所以这块是有可能成为POP链的。
public class InvokerTransformer implements Transformer, Serializable {
根据类的接口来看,这个类是可以序列化的,所以条件都达成。
但是这个类没有readObject的方法,所以payload还需要一个能触发这个反序列化类的地方。
根据对yso的源码查看,我发现CommonsCollections系列的readObject都是在sun.reflect.annotation.AnnotationInvocationHandler里触发readObject。
至于这个类,是在gadget.java里写死的。
public static final String ANN_INV_HANDLER_CLASS = "sun.reflect.annotation.AnnotationInvocationHandler";
在CommonsCollections1里
final InvocationHandler handler = Gadgets.createMemoizedInvocationHandler(mapProxy);
但是目前的构造还需要依赖于触发Map中某一项去调用setValue(),我们需要想办法通过readObject()直接触发
我们观察到java运行库中有这样一个类AnnotationInvocationHandler,这个类有一个成员变量memberValues是Map类型,如下所示
\openjdk\jdk\src\share\classes\sun\reflect\annotation\AnnotationInvocationHandler.java
因此,我们只需要使用前面构造的Map来构造AnnotationInvocationHandler,进行序列化,当触发readObject()反序列化的时候,就能实现命令执行。另外需要注意的是,想要在调用未包含的package中的构造函数,我们必须通过反射的方式,综合生成任意代码执行的payload的代码如下
中途遇到个比我写的好的。可以参考这个来看。
http://blog.0kami.cn/2019/10/24/study-java-deserialized-commonscollections3-1/
对ysoserial工具及java反序列化的一个阶段性理解【未完成】的更多相关文章
- 浅谈java反序列化工具ysoserial
前言 关于java反序列化漏洞的原理分析,基本都是在分析使用Apache Commons Collections这个库,造成的反序列化问题.然而,在下载老外的ysoserial工具并仔细看看后,我发现 ...
- [JAVA反序列化DEMO]利用RMI进行反序列化一键启动工具
功能: 命令行启动jar包,用户自定义启动RMI端口.默认内置Apache Commons Collections.只需一键启动即可测试java反序列化漏洞. 启动服务: [root@sevck_v3 ...
- Java反序列化漏洞通用利用分析
原文:http://blog.chaitin.com/2015-11-11_java_unserialize_rce/ 博主也是JAVA的,也研究安全,所以认为这个漏洞非常严重.长亭科技分析的非常细致 ...
- Java反序列化漏洞分析
相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...
- Java反序列化漏洞之殇
ref:https://xz.aliyun.com/t/2043 小结: 3.2.2版本之前的Apache-CommonsCollections存在该漏洞(不只该包)1.漏洞触发场景 在java编写的 ...
- Lib之过?Java反序列化漏洞通用利用分析
转http://blog.chaitin.com/ 1 背景 2 Java反序列化漏洞简介 3 利用Apache Commons Collections实现远程代码执行 4 漏洞利用实例 4.1 利用 ...
- 通过JBoss反序列化(CVE-2017-12149)浅谈Java反序列化漏洞
前段时间学校学习J2EE,用到了jboss,顺便看了下jboss的反序列化,再浅谈下反序列化漏洞. Java序列化,简而言之就是把java对象转化为字节序列的过程.而反序列话则是再把字节序列恢复为ja ...
- 学习笔记 | java反序列化漏洞分析
java反序列化漏洞是与java相关的漏洞中最常见的一种,也是网络安全工作者关注的重点.在cve中搜索关键字serialized共有174条记录,其中83条与java有关:搜索deserialized ...
- 25. Apache Shiro Java反序列化漏洞
前言: 最近在审核漏洞的时候,发现尽管Apache shiro这个反序列化漏洞爆出来好久了,但是由于漏洞特征不明显,并且shiro这个组件之前很少听说,导致大厂很多服务还存在shiro反序列化的漏洞, ...
随机推荐
- 爬取前尘无忧python职位信息并保存到mongo数据库
1.re实现 import re,os import requests from requests.exceptions import RequestException MAX_PAGE = 10 # ...
- Maven+Docker 部署
Maven+Docker 部署 安装jdk8镜像 docker pull openjdk:8-jdk-alpine maven插件推送方式 修改/etc/docker/daemon.json文件,加入 ...
- Codevs 1038 一元三次方程求解 NOIP 2001(导数 牛顿迭代)
1038 一元三次方程求解 2001年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题目描述 Description 有形如:ax3+b ...
- qt5.6.1 +vs2015 自定义控件 不在designer显示
qt designer 不显示自定义插件, qt5.6.1下在bin下点击designer.exe 打开qdesigner 点击帮助- 关于插件. 显示: 在vs2015 窗口中点击qt vs too ...
- windows下注册表脚本编写
Reg文件就是我今天所说的注册表脚本文件,双击可将其中的数据写入注册表.利用注册表脚本文件可以对注册表进行关于键值的任何操作,而且还不受注册表被禁用的限制. 我们平常对注册表的修改大体上可以分 ...
- php foreach 中使用&时注意
结果: 没看懂的可以参考 :https://blog.csdn.net/ghostyusheng/article/details/79925351
- python的协程,monkeyPatch
monkey patch 一般指运行时候进行动态替换. 基本上我们使用gevent,会在最开头的地方加入gevent.monkey.patch_all();把标准库中的thread/socket等给替 ...
- iOS Jenkins 自动化打包构建
前言 在测试app项目过程中,通常都是需要开发打测试包给到测试,但是无论是iOS还是Android的打包过程都是相当漫长的,频繁的回归测试需要频繁的打包,对于开发同学影响还是蛮大的.因此在这种情况下, ...
- MySQL个人用户的安装配置详解
1. 我的版本是 MySQL 5.7.26.0 ,因为据说 MySQL 8 的性能虽然强悍,但是兼容性还是有问题,而且发布时间不够长,没有普及,就暂时用着5.7版本. (1) 下载地址,选择使用msi ...
- 【Linux】安装 node.js
1.在 linux 上安装 node.js 有几种方式,这里 教的是最简单的一种,因为其他都比较坑. 2.先去 node.js 官网 获取到已经编译好的安装包的地址, 3.使用 wget 去下载上面获 ...