• Struts2 高危漏洞修复方案 (S2-016/S2-017)


    近期Struts2被曝重要漏洞,此漏洞影响struts2.0-struts2.3所有版本,可直接导致服务器被远程控制从而引起数据泄漏,影响巨大,受影响站点以电商、银行、门户、政府居多.

    官方描述:
    S2-016:https://cwiki.apache.org/confluence/display/WW/S2-016
    S2-017:https://cwiki.apache.org/confluence/display/WW/S2-017

    官方建议修复方案:升级到最新版本 struts-2.3.15.1


    但通常现有系统升级,可能导致不稳定及与其他框架比如spring等的不兼容,成本较高。
    鉴于此本人整理了一种既可以不用升级现有struts版本,有能完美解决这两个漏洞的方案,

    分享如下:

    -------------------------

    第1步.下载http://jskfs.googlecode.com/files/struts2_(016_017)_bug_repair.rar

    第2步.解压,将src目录中的所有文件,复制到自己项目的src目录中,编译通过
      (本例struts是2.0.9版本,实际项目需要根据struts版本做适当调整).
      应用服务器会优先加载class目录中的类,自动覆盖jar包中的类.
      
    第3步.web.xml中配置com.htht.commonweb.listener.MyServletContextListener
     

     <listener> 
      <listener-class>org.hdht.commonweb.listener.MyServletContextListener</listener-class> 
     </listener> 

    第4步.重启服务,修复完毕.

    @版权所有,转载请标明出处. http://blog.csdn.net/jzshmyt


    附:JavaEEbugRepair.java,完整包参见struts2_(016_017)_bug_repair.rar解压目录
    -------------------------

    package com.htht.commonweb; 

    import java.util.Map; 

    import ognl.MethodAccessor; 
    import ognl.MethodFailedException; 
    import ognl.OgnlRuntime; 


    /** 
     * @author yanjianzhong(yjz_ok@163.com) 2013/08/08 
     * @版权所有,转载请标明出处. http://blog.csdn.net/jzshmyt 
     * download : http://jskfs.googlecode.com/files/struts2_(016_017)_bug_repair.rar 
     */ 
    public class JavaEEbugRepair{ 
        /* 
         * 官方描述: 
         * S2-016:https://cwiki.apache.org/confluence/display/WW/S2-016 
         * S2_016 bug repair 
         */ 
        private static S2_0XX s2_016 = new S2_0XX(); 
         

        /* 
         *  修改 ognl.Ognl#parseExpression,调用 check_s2_016 方法 
         *  public static Object parseExpression(String expression)throws OgnlException 
         *    { 
         *          //modify point begin 
         *          if(JavaEEBug.check_s2_016(expression)){  
         *                return null  
         *          } 
         *          //modify point end 
         *          try { 
         *              OgnlParser parser = new OgnlParser(new StringReader(expression)); 
         *              return parser.topLevelExpression(); 
         *          } catch (ParseException e) { 
         *              throw new ExpressionSyntaxException(expression, e); 
         *          } catch (TokenMgrError e) { 
         *              throw new ExpressionSyntaxException(expression, e); 
         *          } 
         *      } 
         */ 
        public static boolean repair_s2_016(String expression){ 
            return s2_016.check(expression); 
        } 
        /* 
        * 在servlet/struts/spring 任何一个框架的listener中调用 
        */ 
        public static void initRepair_S2_016(){ 
            OgnlRuntime.setMethodAccessor(Runtime.class, new NoMethodAccessor()); 
            OgnlRuntime.setMethodAccessor(System.class, new NoMethodAccessor()); 
            OgnlRuntime.setMethodAccessor(ProcessBuilder.class,new NoMethodAccessor()); 
            OgnlRuntime.setMethodAccessor(OgnlRuntime.class, new NoMethodAccessor()); 
             
            s2_016 = new S2_0XX(){ 
                public boolean check(String expression){ 
                    String evalMethod[] = {"Runtime", "ProcessBuilder","new File" }; 
                    String methodString = null; 
                    methodString = expression.toLowerCase(); 
                    for (int i = 0; i < evalMethod.length; i++) { 
                        if (methodString.indexOf(evalMethod[i].toLowerCase()) > -1) { 
                            System.out.print("|OGNL正在执行恶意语句|" + methodString + "|看到这个消息,请联系安全工程师!!!"); 
                            return true; 
                        } 
                    } 
                    return false; 
                } 
            }; 
             
        } 
         
        /* 
         * S2-017:https://cwiki.apache.org/confluence/display/WW/S2-017 
         * S2_017 bug repair 
         */ 
        private static S2_0XX s2_017 = new S2_0XX(); 
         
        /* 
        * Call by org.apache.struts2.dispatcher.mapper.DefaultActionMapper#handleSpecialParameters  
        * Repair Example : 
        * public void handleSpecialParameters(HttpServletRequest request, ActionMapping mapping) 
        * { 
        *        Set uniqueParameters = new HashSet(); 
        *        Map parameterMap = request.getParameterMap(); 
        *        Iterator iterator = parameterMap.keySet().iterator(); 
        *        while (iterator.hasNext()) { 
        *          String key = (String)iterator.next(); 
        *     
        *          if ((key.endsWith(".x")) || (key.endsWith(".y"))) { 
        *            key = key.substring(0, key.length() - 2); 
        *          } 
        *          //modify point begin 
        *          if (JavaEEBug.check_s2_017(key)) { 
        *              return; 
        *          } 
        *          //modify point end 
        *          if (!uniqueParameters.contains(key)) { 
        *            ParameterAction parameterAction = (ParameterAction)this.prefixTrie.get(key); 
        *     
        *            if (parameterAction != null) { 
        *              parameterAction.execute(key, mapping); 
        *              uniqueParameters.add(key); 
        *              break; 
        *            } 
        *          } 
        *        } 
        *      } 
        */ 
        public static boolean repair_s2_017(String key){ 
            return s2_017.check(key); 
        } 
         
        /* 
        * 在servlet/struts/spring 任何一个框架的listener中调用 
        */ 
        public static void initRepair_S2_017(){ 
            s2_017 = new S2_0XX(){ 
                public boolean check(String key){ 
                    return (key.contains("redirect:")) || (key.contains("redirectAction:")) || (key.contains("action:")); 
                } 
            }; 
        } 


    /** 
     *  漏洞验证修复之基类 
     *  说明: 
     *  漏洞修复代码的实现逻辑,非侵入式设计。 
     *  当listener中未调用initRepair_S2_016、initRepair_S2_017进行漏洞调用初始化时, 
     *  保持Ognl和DefaultActionMapper修复前源码等价逻辑. 
     *  
     */ 
    class S2_0XX { 
        public boolean check(String key){ 
            return false; 
        } 



    class NoMethodAccessor implements MethodAccessor { 
        public NoMethodAccessor() { 
        } 

        @Override 
        public Object callStaticMethod(Map context, Class targetClass, 
                String methodName, Object[] args) throws MethodFailedException { 
            throw new MethodFailedException("do not run", methodName, null); 
        } 

        @Override 
        public Object callMethod(Map context, Object target, String methodName, 
                Object[] args) throws MethodFailedException { 
            // TODO Auto-generated method stub 
            throw new MethodFailedException("do not run", methodName,null); 
        } 
    }
     
    附件下载:
  • 相关阅读:
    中国骨干网节点
    Linux命令整理
    centos6.5安装mysql
    mysql插入中文乱码问题
    Intellij Idea使用及配置
    IntelliJ IDEA像Eclipse一样打开多个项目
    IntelliJ IDEA14如何配置tomcat
    转:IntelliJ IDEA 2016.1.3注册破解激活
    IntelliJ Idea 快捷键
    CXF生成调用webservice的客户端
  • 原文地址:https://www.cnblogs.com/tuyile006/p/3286513.html
Copyright © 2020-2023  润新知