设为首页 - 加入收藏 - 网站地图 SecYe安全 Www.SecYe.Com - 国内网络信息安全IT技术门户网
当前位置:SecYe > 网络安全 > 系统和服务器安全 > 正文

Struts2 S2-020在Tomcat 8下的命令执行分析

时间:2014-04-05 12:01 来源:sec.baidu.com 作者:neobyte 阅读:

Struts S2-020这个通告已经公布有一段时间了。目前大家都知道这个漏洞可以造成DOS、文件下载等危害,相信各大厂商也已经采取了相应的安全措施。今天是和大家分享一下对这个漏洞的一点研究,包括如何在Tomcat 8下导致RCE,目的是抛砖引玉,有不足之处欢迎大家指出。

1.属性列举

这个漏洞分析的一个难点在于:通过ognlclass.xx这种方式来遍历属性时,得到的是实际运行环境中的动态class,因此仅作静态分析是很困难的。例如classLoader,在不同容器中就各不相同。于是我编写了一个小脚本来自动枚举这样的属性:(这段脚本只考虑了intstringboolean这些基本属性,未考虑数组等复杂的情况,实际情况下结果会更多)

<%@ page language="java" import="java.lang.reflect.*" %>
<%!
public void processClass(Object instance, javax.servlet.jsp.JspWriter out, java.util.HashSet set, String poc){
	try {
	    Class<?> c = instance.getClass();
	    set.add(instance);
	    Method[] allMethods = c.getMethods();
	    for (Method m : allMethods) {
		if (!m.getName().startsWith("set")) {
		    continue;
		}
		if (!m.toGenericString().startsWith("public")) {
		    continue;
		}
		Class<?>[] pType  = m.getParameterTypes();
		if(pType.length!=1) continue;

		if(pType[0].getName().equals("java.lang.String")||
		pType[0].getName().equals("boolean")||
		pType[0].getName().equals("int")){
			String fieldName = m.getName().substring(3,4).toLowerCase()+m.getName().substring(4);
			out.print(poc+"."+fieldName + "<br>");
		}
	    }
	    for (Method m : allMethods) {
		if (!m.getName().startsWith("get")) {
		    continue;
		}
		if (!m.toGenericString().startsWith("public")) {
		    continue;
		}		
		Class<?>[] pType  = m.getParameterTypes();
		if(pType.length!=0) continue;
		if(m.getReturnType() == Void.TYPE) continue;
		Object o = m.invoke(instance);
		if(o!=null)
		{
			if(set.contains(o)) continue;
			processClass(o,out, set, poc+"."+m.getName().substring(3,4).toLowerCase()+m.getName().substring(4));	
		} 
	    }
	} catch (java.io.IOException x) {
	    x.printStackTrace();
	} catch (java.lang.IllegalAccessException x) {
	    x.printStackTrace();
	} catch (java.lang.reflect.InvocationTargetException x) {
	    x.printStackTrace();
	} 	
}
%>
<%
java.util.HashSet set = new java.util.HashSet<Object>();
String poc = "class.classLoader";
example.HelloWorld action = new example.HelloWorld();
processClass(action.getClass().getClassLoader(),out,set,poc);
%>

tomcat 8.0.3Struts2.3.16blank app中执行这段jsp,输出结果如下:

(省略部分非相关属性)
class.classLoader.resources.context.parent.pipeline.first.encoding
class.classLoader.resources.context.parent.pipeline.first.directory
class.classLoader.resources.context.parent.pipeline.first.checkExists
class.classLoader.resources.context.parent.pipeline.first.renameOnRotate
class.classLoader.resources.context.parent.pipeline.first.fileDateFormat
class.classLoader.resources.context.parent.pipeline.first.prefix
class.classLoader.resources.context.parent.pipeline.first.rotatable
class.classLoader.resources.context.parent.pipeline.first.buffered
class.classLoader.resources.context.parent.pipeline.first.suffix
class.classLoader.resources.context.parent.pipeline.first.locale
class.classLoader.resources.context.parent.pipeline.first.requestAttributesEnabled
class.classLoader.resources.context.parent.pipeline.first.enabled
class.classLoader.resources.context.parent.pipeline.first.conditionUnless
class.classLoader.resources.context.parent.pipeline.first.conditionIf
class.classLoader.resources.context.parent.pipeline.first.pattern
class.classLoader.resources.context.parent.pipeline.first.condition
class.classLoader.resources.context.parent.pipeline.first.asyncSupported
class.classLoader.resources.context.parent.pipeline.first.domain
class.classLoader.resources.context.parent.pipeline.first.next.asyncSupported
class.classLoader.resources.context.parent.pipeline.first.next.domain
class.classLoader.resources.context.parent.pipeline.first.next.next.asyncSupported
class.classLoader.resources.context.parent.pipeline.first.next.next.domain
......	
	

本文来源:SecYe安全网[http://www.secye.com] (责任编辑:SecYe安全)

点击复制链接 与好友分享!

顶一下
(0)
0%
踩一下
(0)
0%