-
Notifications
You must be signed in to change notification settings - Fork 660
/
Copy pathAntObjectInputStream.java
80 lines (62 loc) · 2.75 KB
/
AntObjectInputStream.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package org.joychou.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
/**
* RASP:Hook java/io/ObjectInputStream类的resolveClass方法
* RASP: https://github.com/baidu/openrasp/blob/master/agent/java/engine/src/main/java/com/baidu/openrasp/hook/DeserializationHook.java
*
* Run main method to test.
*/
public class AntObjectInputStream extends ObjectInputStream {
protected final Logger logger= LoggerFactory.getLogger(AntObjectInputStream.class);
public AntObjectInputStream(InputStream inputStream) throws IOException {
super(inputStream);
}
/**
* 只允许反序列化SerialObject class
*
* 在应用上使用黑白名单校验方案比较局限,因为只有使用自己定义的AntObjectInputStream类,进行反序列化才能进行校验。
* 类似fastjson通用类的反序列化就不能校验。
* 但是RASP是通过HOOK java/io/ObjectInputStream类的resolveClass方法,全局的检测白名单。
*
*/
@Override
protected Class<?> resolveClass(final ObjectStreamClass desc)
throws IOException, ClassNotFoundException
{
String className = desc.getName();
// Deserialize class name: org.joychou.security.AntObjectInputStream$MyObject
logger.info("Deserialize class name: " + className);
String[] denyClasses = {"java.net.InetAddress",
"org.apache.commons.collections.Transformer",
"org.apache.commons.collections.functors"};
for (String denyClass : denyClasses) {
if (className.startsWith(denyClass)) {
throw new InvalidClassException("Unauthorized deserialization attempt", className);
}
}
return super.resolveClass(desc);
}
public static void main(String args[]) throws Exception{
// 定义myObj对象
MyObject myObj = new MyObject();
myObj.name = "world";
// 创建一个包含对象进行反序列化信息的/tmp/object数据文件
FileOutputStream fos = new FileOutputStream("/tmp/object");
ObjectOutputStream os = new ObjectOutputStream(fos);
// writeObject()方法将myObj对象写入/tmp/object文件
os.writeObject(myObj);
os.close();
// 从文件中反序列化obj对象
FileInputStream fis = new FileInputStream("/tmp/object");
AntObjectInputStream ois = new AntObjectInputStream(fis); // AntObjectInputStream class
//恢复对象即反序列化
MyObject objectFromDisk = (MyObject)ois.readObject();
System.out.println(objectFromDisk.name);
ois.close();
}
static class MyObject implements Serializable {
public String name;
}
}