JAVA反序列化修复总结

作者: Franchen | 来源:发表于2019-08-21 18:30 被阅读1次

    威胁说明

    如果Java应用对用户输入,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输入,让反序列化产生非预期的对象,非预期的对象在产生过程中就有可能带来任意代码执行。

    问题原因

    • ObjectInputStream在反序列化时,没有对生成的对象的输入做限制,使攻击者利用反射调用函数进行任意命令执行。
    • CommonsCollections组件中对于集合的操作存在可以进行反射调用的方法

    问题根源

    Apache Commons Collections允许链式的任意的类函数反射调用。

    问题函数

    org.apache.commons.collections.Transformer接口

    问题版本

    3.2.2之前所有版本

    快速排查

    目前打包有apache commons collections库并且应用比较广泛的主要中间件有JenkinsWebLogicJbossWebSphereOpenNMS等。

    如果使用了以上中间件,需检测中间件安装目录是否包含apache commons collections库及其版本。特别是项目中发现使用了readObject函数。如:

    ls -R 安装目录 | grep commons-collections.jar
    ls -R 安装目录 | grep *.commons-collections.jar
    ls -R 安装目录 | grep apache.commons.collections.jar
    ls -R 安装目录 | grep *.commons-collections.*.jar
    

    如果包含,且版本低于3.2.2,请参考修复建议。

    修复建议

    1. 通用修复方案

    方法:更新Apache Commons Collections库至3.2.2及以上版本。

    警告:此方法为中间件上游修复方案,如果使用了中间件,请查看对应中间件的修复方案。

    官方版本说明:https://commons.apache.org/proper/commons-collections/release_3_2_2.html


    2. spring-boot-starter-actuator

    • 仅开放需要的接口:
    endpoints.enabled = false
    endpoints.metrics.enabled = true
    
    • 开启账户密码认证:
    1. 引入spring-boot-starter-security依赖
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    
    1. 在application.properties中指定actuator的端口以及开启security功能,配置访问权限验证:
    management.port=8099
    management.security.enabled=true
    security.user.name=xxxxx
    security.user.password=xxxxxx
    

    参考链接:
    https://xz.aliyun.com/t/2233
    https://www.jianshu.com/p/3162ce30a853


    3. Jboss

    影响版本:

    Platform Package State
    Red Hat Subscription Asset Manager 1 jasperreports-server-pro 受攻击
    Red Hat OpenStack Platform 8.0 (Liberty) opendaylight 无影响
    Red Hat JBoss Portal 5 jbossas 受攻击
    Red Hat JBoss Fuse Service Works 6 jbossas 受攻击
    Red Hat JBoss Enterprise SOA Platform 5 JBossAS 受攻击
    Red Hat JBoss Enterprise SOA Platform 5 jbossas 受攻击
    Red Hat JBoss Enterprise SOA Platform 4 JBossAS 受攻击
    Red Hat JBoss EWS 2 tomcat 无影响
    RHEV Manager 3 jasperreports-server-pro 受攻击

    官方升级补丁:https://access.redhat.com/security/cve/cve-2015-7501


    4. WebLogic

    影响版本:10.3.6.012.1.2.012.1.3.012.2.1.0

    官方升级补丁:https://www.oracle.com/technetwork/topics/security/alert-cve-2015-4852-2763333.html


    5. jenkins

    影响版本:

    • 所有低于1.637Jenkins主线版本,包括1.637
    • 所有低于1.625.1Jenkins LTS版本,包括1.625.1

    修复方案:(参考:https://jenkins.io/security/advisory/2015-11-11/

    • Jenkins主线版本用户应该升级至1.638或以上。
    • Jenkins LTS版本用户应该升级至1.625.2或以上。

    临时方案:(参考https://github.com/jenkinsci-cert/SECURITY-218

    1. 在Groovy脚本控制台(/script)运行下面的代码,这将关闭正在运行的Jenkins的CLI子系统,而无需重新启动。
    2. 将下面的代码放到$JENKINS_HOME/init.groovy.d/cli-shutdown.groovy,保证确保在主机重启后保护保持不变。
    import jenkins.*;
    import jenkins.model.*;
    import hudson.model.*;
    
    // disabled CLI access over TCP listener (separate port)
    def p = AgentProtocol.all()
    p.each { x ->
      if (x.name.contains("CLI")) p.remove(x)
    }
    
    // disable CLI access over /cli URL
    def removal = { lst ->
      lst.each { x -> if (x.getClass().name.contains("CLIAction")) lst.remove(x) }
    }
    def j = Jenkins.instance;
    removal(j.getExtensionList(RootAction.class))
    removal(j.actions)
    

    6. websphere

    影响版本:

    • WebSphere Application Server ND Version V9.0.0.0 – V9.0.0.11
    • WebSphere Application Server ND Version V8.5.0.0 – V8.5.5.15
    • WebSphere Virtual Enterprise Version 7.0(官方已停止维护)

    官方补丁:

    提示:以上IBM提供的补丁连接,需输入登录账号后才能下载。

    注意:在打补丁之前请先关闭WebSphere服务,安装完成后再将服务开启。


    7. 临时方案

    如果无法打补丁,以下为各中间件官方推荐的临时方案:

    • 方式1:使用SerialKiller替换进行序列化操作的ObjectInputStream类。

    • 方式2:在不影响业务的情况下,删除所有commons-collections包中的InvokerTransformer.classInstantiateFactory.classInstantiateTransformer.class,例如:

    zip -d commons-collections-3.2.1.redhat-3.jar org/apache/commons/collections/functors/InvokerTransformer.class
    

    警告:临时方案中任何变动都需手动验证业务可用性。


    8. 强制封禁方案

    严格意义说起来,Java相对来说安全性问题比较少,出现的一些问题大部分是利用反射,最终用Runtime.exec(String cmd)函数来执行外部命令的。

    如果可以禁止JVM执行外部命令,未知漏洞的危害性会大大降低,可以大大提高JVM的安全性。

    如下,只要在Java代码里简单加一段程序,就可以禁止执行外部程序了。

    SecurityManager originalSecurityManager = System.getSecurityManager();
    if (originalSecurityManager == null) {
        // 创建自己的SecurityManager
        SecurityManager sm = new SecurityManager() {
            private void check(Permission perm) {
                // 禁止exec
                if (perm instanceof java.io.FilePermission) {
                    String actions = perm.getActions();
                    if (actions != null &amp;&amp; actions.contains("execute")) {
                        throw new SecurityException("execute denied!");
                    }
                }
                // 禁止设置新的SecurityManager
                if (perm instanceof java.lang.RuntimePermission) {
                    String name = perm.getName();
                    if (name != null &amp;&amp; name.contains("setSecurityManager")) {
                        throw new SecurityException(
                        "System.setSecurityManager denied!");
                    }
                }
            }
            @Override
            public void checkPermission(Permission perm) {
                check(perm);
            }
            @Override
            public void checkPermission(Permission perm, Object context) {
                check(perm);
            }
        };
        System.setSecurityManager(sm);
    }
    

    相关文章

      网友评论

        本文标题:JAVA反序列化修复总结

        本文链接:https://www.haomeiwen.com/subject/vgwisctx.html