本文为悬镜安全实验室成员原创投稿,如需转载,需标注来源以及原文链接。
年的1月28号,GabrielLawrence(
gebl)和ChrisFrohoff(frohoff)在AppSecCali上给出了一个报告[3],报告中介绍了Java反序列化漏洞可以利用ApacheCommonsCollections这个常用的Java库来实现任意代码执行。同年11月6日,FoxGloveSecurity安全团队的
breenmachine在一篇博客中[2]介绍了如何利用Java反序列化漏洞,来攻击最新版的WebLogic、WebSphere、JBoss、Jenkins、OpenNMS这些大名鼎鼎的Java应用,实现远程代码执行。距离漏洞发布已经有了一年多的时间,仍然有很多网站仍未修复漏洞。
1.漏洞原理1.1Java序列化与反序列化简单的说,把对象转换为字节序列的过程称为对象的序列化。把字节序列恢复为对象的过程称为对象的反序列化。
Java序列化的目的是为了将某些对象存储到磁盘上,从而长期保存,例如最常见的是Web服务器中的Session对象,当有10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
或者当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。
发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
一个序列化与反序列化的典型场景如下:
```importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.ObjectInputStream;importjava.io.ObjectOutputStream;publicclassdeserial{publicstaticvoidmain(Stringargs[])throwsException{Stringobj="helloworld!";
//将序列化对象写入文件object.db中FileOutputStreamfos=newFileOutputStream("object.db");ObjectOutputStreamos=newObjectOutputStream(fos);os.writeObject(obj);os.close();//从文件object.db中读取数据FileInputStreamfis=newFileInputStream("object.db");ObjectInputStreamois=newObjectInputStream(fis);//通过反序列化恢复对象objStringobj2=(String)ois.readObject();System.out.println(obj2);ois.close();}
}```
1.2Java反序列化漏洞Java反序列化漏洞的核心在于,由于Java中的类ObjectInputStream在反序列化时,没有对生成的对象的类型做限制。
在反序列化的时候不需要指定原来的数据类型即可进行反序列化。如下代码仍可以执行importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.ObjectInputStream;importjava.io.ObjectOutputStream;publicclassdeserial{publicstaticvoidmain(Stringargs[])throwsException{Stringobj="helloworld!";//将序列化对象写入文件object.db中FileOutputStreamfos=newFileOutputStream("object.db");ObjectOutputStreamos=newObjectOutputStream(fos);os.writeObject(obj);os.close();//从文件object.db中读取数据FileInputStreamfis=newFileInputStream("object.db");ObjectInputStreamois=newObjectInputStream(fis);//通过反序列化恢复对象objObjectobj2=ois.readObject();System.out.println(obj2);ois.close();}}那么对用户输入,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在产生过程中就有可能带来任意代码执行。
反序列漏洞由来已久,PHP和Python中也有同样的问题,而在Java中问题比较严重的原因是因为一些公用库,例如ApacheCommonsCollections中实现的一些类可以被反序列化用来实现任意代码执行。
WebLogic、WebSphere、JBoss、Jenkins、OpenNMS这些应用的反序列化漏洞能够得以利用,就是依靠了ApacheCommonsCollections。
但是该漏洞的根源并不在于公共库,而是在于Java没有对反序列化生成的对象的类型做限制。正如某些评论所说:
1.3漏洞利用原理该漏洞的出现的根源在CommonsCollections组件中对于集合的操作存在可以进行反射调用的方法,并且该方法在相关对象反序列化时并未进行任何校验,新版本的修复方案对相关反射调用进行了限制。
1.3.1InvokerTransformer.transform()实现程序执行问题函数主要出现在org.apache.北京治疗白癜风的最好医院怎么样才能治疗白癜风