java 反射和反序列化破解单例模式和填补漏洞方法

反射:

    public class Destruct {

    public static void main(String[] args) throws Exception {

        Class clazz=Class.forName("co.sxt.in.Design");
        Constructor<Design> c=clazz.getDeclaredConstructor(); 
        c.setAccessible(true);  //访问私有属性跳过安全检查
        Design d3=c.newInstance();
        Design d4=c.newInstance();

        System.out.println(d3);
        System.out.println(d4); //此时会创建两个不同的对象

}

反序列化

public class Destruct {

public static void main(String[] args) throws Exception {
        //通过反序列化的方式构建对象
        FileOutputStream fos=new FileOutputStream("d:/ak.txt");
        ObjectOutputStream oos=new ObjectOutputStream(fos);
        oos.writeObject(d);
        oos.close();
        fos.close();

        FileInputStream fis=new FileInputStream("d:/ak.txt");
        ObjectInputStream ois=new ObjectInputStream(fis);
        Object obj=ois.readObject();

        if(obj instanceof Design)
        {
            Design d5=(Design)obj;
            System.out.println(d==d5);  //通过返序列化创建了不同对象
        }

}

弥补漏洞:

弥补反射漏洞

public class Design implements Serializable{
private static Design d;

    private Design() {
        f(d!=null)
        {
            throw new RuntimeException();
        } 
    };
    public static synchronized Design getInstance()
    {
        if(d==null)
        {
            d=new Design();
        }
        return d;
    }

}

弥补反序列化漏洞:

public class Design implements Serializable{
private static Design d;

    private Design() {

    };
    public static synchronized Design getInstance()
    {
        if(d==null)
        {
            d=new Design();
        }
        return d;
    }
     破解反序列化漏洞,反序列化时如果定义了返回对象的方法,则直接调方法返回,而不需要再反序列化一个新对象
        private Object readResolve() throws ObjectStreamException{
    return instance;
} 

}

猜你喜欢

转载自blog.51cto.com/14437184/2440143