Struts2漏洞修复方案

Struts2漏洞修复方案Struts2漏洞修复方案近期Struts2被曝重要漏洞,此漏洞影响struts2.0-struts2.3所有版本,可直接导致服务器被远程控制从而引起数据泄漏,影响巨大,受影响站点以电商、银行、门户、政府居多.官方描述:S2-016:https://cwiki.apache.org/confluence/display/WW/S2-016S2-0

大家好,又见面了,我是你们的朋友全栈君。

Struts2漏洞修复方案

近期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。(被墙了)

     http://files.cnblogs.com/MarkMai/struts2-016-017-bug-repair.zip

第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); 
    } 
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/161679.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号