拖了很久,迟早是要学的
环境配置
配置Maven
下载地址:
https://archive.apache.org/dist/maven/maven-3/
参考链接里,作者说不建议下载太高版本,经笔者测试,3.6.3 idea报错,解决方案就是降版本。我用的eclipse没问题。
解压后,在conf目录找到settings.xml,修改local repo以及换镜像
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
配置环境变量,查看参考链接里的就行了,很详细
使用eclipse来新建maven项目
eclipse中创建maven项目,创建项目后如果报错
CoreException: Could not get the value for parameter compilerId for plugin e...
按ALT+F5勾选Force Update of Snapshots/Releases,然后关闭eclipse,就会自动下载需要的文件。
添加漏洞组件
按照参考链接创建好maven项目后,在项目的文件夹里有一个pom.xml,添加我们需要的组件
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
然后在包含pom.xml的目录下打开命令行窗口,执行下面的命令,maven就会去下载我们要的组件
call mvn -f pom.xml dependency:copy-dependencies
漏洞原理探究
参考
Java反序列化漏洞的原理分析
对如下利用链进行跟踪分析
BadAttributeValueExpException 中的属性 Object val --> TiedMapEntry
TiedMapEntry 的 toString() 方法调用了自身map属性的getValue() 方法 --> LazyMap
LazyMap的getValue拿到的必然是一个空对象,因此会触发LazyMap属性中配置的Transformer.transform()
Transformer 是我们构建的包含有恶意代码的对象
Java中的反射
Student 类
public class Student {
public void show(String s){
System.out.println("s=" + s);
}
}
fanshe类,可以看到并没有import student
类,但是可以通过Class.forName("Student");
来获取Student
类,并通过getMethod
方法来获取Student
类的方法,最终调用该方法
import java.lang.reflect.Method;
public class fanshe{
public static void main(String[] args) throws Exception {
Class stuClass = Class.forName("Student");
Method m = stuClass.getMethod("show", String.class);
System.out.println(m);
Object obj = stuClass.getConstructor().newInstance();
m.invoke(obj, "2333");
}
}
TransformedMap
TransformedMap是Commons-collections 3.1提供的一个工具类,用来包装一个Map对象,并且在该对象的Entry的Key或者Value进行改变的时候,利用Transformer提供的转换操作对该Key和Value进行转换。
当TransformedMap对象执行setValue方法时会调用valueTransformer的transform方法,如果传入的valueTransformer是ChainedTransformer的对象,可以造成恶意代码执行。
...
public class TransformedMap
extends AbstractInputCheckedMapDecorator
implements Serializable {
/** Serialization version */
private static final long serialVersionUID = 7023152376788900464L;
/** The transformer to use for the key */
protected final Transformer keyTransformer;
/** The transformer to use for the value */
protected final Transformer valueTransformer;
...
public static Map decorate(Map map, Transformer keyTransformer, Transformer valueTransformer) {
return new TransformedMap(map, keyTransformer, valueTransformer);
}
protected TransformedMap(Map map, Transformer keyTransformer, Transformer valueTransformer) {
super(map);
this.keyTransformer =