首页 > 代码库 > 重现Struts1的操纵classLoader漏洞
重现Struts1的操纵classLoader漏洞
2014年4月29日爆出的struts的可操纵classLoader的漏洞, 横跨struts1和struts2的所有版本。 影响面和问题的严重性几乎可以和heartbleed相媲美。 struts2要严重一些,对于struts1,只是说在特定条件下可执行特殊操作。
因为项目中用的是struts1,所以主要精力集中在struts1上。既然要修复漏洞,首先得找出POC给老板看,这类漏洞一般网上不会给出直接的POC,于是就动手捣鼓一番。建立一个简单的struts1项目,包含一个Action和ActionForm即可。 启用debug模式部署项目到tomcat等容器。然后在action的任意位置加一个断点,然后通过浏览器访问该action。既然说是"操纵classLoader",我马上想到的是struts自动封装表单用到反射,在断点附近寻找ActionForm的class的classLoader的属性列表,看看有谁的名字听起来是可操纵的。最初我就发现了这个:clearReferencesHttpClientKeepAliveThread .于是有如下的url和截图:
http://localhost:8080/Struts1/helloWorld.do?class.classLoader.clearReferencesHttpClientKeepAliveThread=false
http://localhost:8080/Struts1/helloWorld.do?class.classLoader.clearReferencesHttpClientKeepAliveThread=true
至此classLoader操作成功, 尽管clearReferencesHttpClientKeepAliveThread是一个暂时看起来不太危险的classLoader属性。
我看到部分资料说该漏洞在jetty7 下可关闭jetty服务器, 我也试了, 可以, 你可以把项目部署到jett7, 然后用如下url:
http://localhost:8080/Struts1/helloWorld.do?class.classloader.context.shutdown=true
一旦class.classloader.context.shutdown被输入,则后续的所有请求都只能收到404,要想恢复的唯一办法就是重启jetty。
如图:
还有更多的其他的POC比如在tomcat8下可下载任意文件,在其他情况下可执行code等待,我就没有一一证明。
因为struts1在该漏洞发出后, apache宣布struts1即将EOL, 所以我们也不打算花太多精力搞个威猛的方案出来,用了一个filter来检查请求参数是否包含“class.*”完事。代码片段如下:
public static final String classLoaderManipulatorParamReg = "(class\\.)|(class.classLoader\\.)" ; public static final Pattern classLoaderManipulatorParamPattern = Pattern.compile(classLoaderManipulatorParamReg); Enumeration<String> params = request.getParameterNames(); while(params.hasMoreElements()){ String key = params.nextElement(); Matcher matcher = classLoaderManipulatorParamPattern.matcher(key); if(matcher.find()){ System.out.println("suspicious parameters: " + key + ", removed from the parameter list."); req.setAttribute("msg", key+"=" + req.getParameter(key)); request.getRequestDispatcher("unsafeRequest.jsp").forward(req, response); //logger.warn(this, "suspicious parameter: " + key); // 需替换尖括号以防止反射型的XSS漏洞 String kvPair = (key+"=" + req.getParameter(key)).replaceAll("<", "& lt;").replaceAll(">","& gt;"); /* * 这里需要注意:如果用以下方式重定向到出错页面, 极有可能导致递归的filter调用从而进入死循环。 * request.getRequestDispatcher("unsafeRequest.jsp").forward(req, response); * 如果你想走到一个单独的出错页面来显示错误信息, 需要谨慎处理。 * 我们这里就简单的直接输出出错信息到response. */ response.getWriter().write("Malicious parameter detected: " + kvPair); response.getWriter().flush(); return; } }
你可以在这里下载struts1样例程序: http://download.csdn.net/detail/sunxing007/7350433。如要重现POC, 请先把web.xml中SecurityFilter去掉。
转载请注明来自: http://blog.csdn.net/sunxing007