您的位置:首页 > 编程语言 > Java开发

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

2013-09-09 23:26 411 查看
近期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);

}

}

附件尺寸
下载

struts2-016-017-bug-repair.zip
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: