您的位置 首页 java

反序列化攻击原理及防御措施(已解决)

java 序列化算法透析

序列化的必要性

Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端。

这就需要有一种可以在两端传输数据的协议。Java序列化机制就是为了解决这个问题而产生

如何进行序列化

 public class Java_Test {
    public  static   void  main(String args[]) throws  Exception  {
       Peoper peoper = new Peoper();
       // peoper1.setAge(6);
        peoper.setName("zy");
        //peoper1.setJob("6666666666");

        // 将序列化对象写入文件object.txt中
         FileOutputStream  fos = new FileOutputStream("object.ser");
        ObjectOutputStream os = new ObjectOutputStream(fos);
        os.writeObject(peoper);
        os.close();

        // 从文件object.txt中读取数据
         FileInputStream  fis = new FileInputStream("object.ser");
        ObjectInputStream ois = new Object InputStream (fis);
        //MyObjectInputStream ois = new MyObjectInputStream(fis);
        //ObjectInputStream ois = new ObjectInputStream(fis);
        // 通过反序列化恢复对象obj
        Peoper peoper1 = (Peoper) ois.readObject();
        System.out.println(peoper1);
        ois.close();
    }
}  

序列化漏洞发生的位置

在反序列化的过程中,我们通过ObjectInputStream来进行 字节码 的读取,但是在该类中没有对将要序列化的对象进行校验。攻击者则可以通过构造POC的方式,把自己构造的对象提交到服务器,服务器在反序列化的工程中会执行readObject方法,而此方法可以在构造的对象中重写。

通过改变transferedMap的key或则value值来触发transferChain的系统函数的执行,从而控制服务器,造成严重的损失。

解决方案原理核心

通过重写ObjectInputStream的resolveClass方法对即将序列化的对象进行校验(在反序列化之前进行),从而达到避免反序列化漏洞的风险。

解决方法具体代码如下

 public class MyObjectInputStream  extends  ObjectInputStream {
    public MyObjectInputStream(InputStream in) throws IOException {
        super(in);
    }

    protected MyObjectInputStream() throws IOException, SecurityException {
    }

    @Override
    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        if (desc == null) {
            return super.resolveClass(desc);
        }
         if  (!desc.getName().equals(Peoper.class.getName())) {
            throw new InvalidClassException("不能序列化,可能有攻击",desc.getName());
        }
        return super.resolveClass(desc);
    }
}  

在实际开发过程中代码示例

 public class MyObjectInputStream extends ObjectInputStream {
    public MyObjectInputStream(InputStream in) throws IOException {
        super(in);
    }

    protected MyObjectInputStream() throws IOException, SecurityException {
    }

    @Override
    protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
        if (desc == null) {
            return super.resolveClass(desc);
        }
        if (!desc.getName().contains("被序列化对象包名")) {
            throw new InvalidClassException("不能序列化,可能有攻击",desc.getName());
        }
        return super.resolveClass(desc);
    }
}  

以上是个人处理方式以及见解,如有不妥之处,希望之处!!!!

文章来源:智云一二三科技

文章标题:反序列化攻击原理及防御措施(已解决)

文章地址:https://www.zhihuclub.com/196206.shtml

关于作者: 智云科技

热门文章

网站地图