ObjectInputStream.readObject
ObjectInputStream.readUnshared
XMLDecoder.readObject
Yaml.load
XStream.fromXML
ObjectMapper.readValue
JSON.parseObject
"/test") (
public String test() {
String obj = "hello world!";
try {
// 创建一个包含对象进行反序列化信息的”object”数据文件
FileOutputStream fos = new FileOutputStream("object");
ObjectOutputStream os = new ObjectOutputStream(fos);
// writeObject()方法将obj对象写入object文件
os.writeObject(obj);
os.close();
// 从文件中反序列化obj对象
FileInputStream fis = new FileInputStream("object");
ObjectInputStream ois = new ObjectInputStream(fis);
// 恢复对象
String obj2 = (String) ois.readObject();
ois.close();
return obj2;
} catch (Exception e) {
return e.toString();
}
}
3 漏洞代码 readObject,读取输入流,并转换对象。 ObjectInputStream.readObject() 方法的作用正是从一个源输入流中读取字节序列,再把它们反序列化为一个对象。 如果此时ObjectInputStream对象的初始化参数来自外部请求输入参数则基本可以确定存在反序列化漏洞 @RequestMapping("/readObject")
public String readObject(String base64) {
try {
System.out.println("[vul] 执行反序列化");
BASE64Decoder decoder = new BASE64Decoder();
// 坑:读取的base64内容,加号会被转空格
base64 = base64.replace(" ", "+");
byte[] bytes = decoder.decodeBuffer(base64);
// 将字节转为输入流
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
// 反序列化流,将序列化的原始数据恢复为对象
ObjectInputStream in = new ObjectInputStream(stream);
in.readObject();
in.close();
return "反序列化漏洞";
} catch (Exception e) {
return "需生成Payload:java -jar ysoserial-0.0.6-SNAPSHOT-BETA-all.jar CommonsCollections5 "open -a Calculator" | base64";
}
}
4 安全代码 使用Apache Commons IO的ValidatingObjectInputStream,accept方法来实现反序列化类白/黑名单控制 @RequestMapping("/safe")
public String safe(String base64) {
try {
System.out.println("[safe] 执行反序列化");
BASE64Decoder decoder = new BASE64Decoder();
// 坑:读取的base64内容,加号会被转空格
base64 = base64.replace(" ", "+");
byte[] bytes = decoder.decodeBuffer(base64);
// 将字节转为输入流
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
// 使用 ValidatingObjectInputStream
ValidatingObjectInputStream ois = new ValidatingObjectInputStream(stream);
// 只允许反序列化Student class
ois.accept(Student.class);
Object obj = ois.readObject();
return "ValidatingObjectInputStream";
} catch (Exception e) {
return e.toString();
}
}
5 编码建议 1.更新commons-collections、commons-io等第三方库版本; 2.业务需要使用反序列化时,尽量避免反序列化数据可被用户控制,如无法避免建议尽量使用白名单校验的修复方式 6 代码链接 https://github.com/j3ers3/Hello-Java-Sec
7 历史文章 Java代码审计:SQL注入 Java代码审计:XSS与SSRF Java代码审计:远程代码执行 原文始发于微信公众号(Reset安全):Java代码审计:反序列化
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论