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([email protected]) 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);
}
}



注:原文地址爲http://software.intel.com/zh-cn/blogs/2013/08/08/struts2-s2-016s2-017/?utm_campaign=CSDN&utm_source=intel.csdn.net&utm_medium=Link&utm_content=others-%20Struts2

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章