详情来源: [ADLab](https://mp.weixin.qq.com/s?__biz=MzAwNTI1NDI3MQ==&mid=2649611817&idx=1&sn=22c8b5372f668fed73dd67fb23e015fc&scene=1&srcid=0712SIUX6Qm8UMxXyqQqBnR0&key=77421cf58af4a6539af7a7faaa29aa568c54411ee815838f23cea97588c0a054bd5d8be2d3bec0c8050eb5237bab6537&ascene=0)
> 启明星辰ADLab研究人员发现,当Struts2中的devMode模式设置为true时,存在严重远程代码执行漏洞。如果WebService 启动权限为最高权限时,可远程执行任意命令,包括关机、建立新用户、以及删除服务器上所有文件等等。
受影响版本:Struts 2.1.0--2.5.1
> 2016年6月,启明星辰ADLab已将此漏洞提交至Struts2官方,Struts2官方表示此漏洞为开发者模式下存在的问题,关闭devMode即可避免此问题发生。由于官方已经明确警示用户,发布系统时须关闭devMode,因此此次漏洞通报不会进入他们的漏洞处理流程。
### Struts2远程执行任意代码漏洞利用技术浅析
Struts2远程执行任意代码漏洞,历史上出现过很多次。在这里回顾下其中两个具有代表性的历史漏洞,主要侧重于他们是如何突破系统防线、绕过系统过滤的。
** 1、S2-008漏洞 **
S2-008漏洞也是一个devMode下的远程执行漏洞,由于当时Apache还没有专门的声明,要求开发者在发布系统的时候必须关闭devMode,因此这个漏洞当时还是被他们给予了CVE编号,并在后续比较迟的时候增加了对其利用方式的过滤处理。
CVE编号授予的时候,Struts2的最新版本为2.3.1,但在其后直至2.3.28之前的版本都能够触发这个漏洞,从2.3.29开始,官方增加了一个检查项——禁止链式表达式,这才阻止了特定ognl表达式的执行。但是不得不说该漏洞一直存在,只是利用条件变得越来越苛刻。
我们在此做一个纯技术分析的分享:
该漏洞的主要问题出在DebuggingInterceptor这个类,从名字上可以看出是个拦截器,如果devMode开启的话,这个拦截器就会检测提交的debug参数是否含有下面几个MODE选项。

通过分析代码发现,command、browser这两个模式调用了stack.findValue这个方法,正是这个方法将用户提交的数据送到了ognl解析器里作为ognl表达式执行。
这里以debug=browser&object=xxx为例,相关代码如下。

在2.3.28及之前版本中,rootObjectExpression没有任何过滤直接由stack.findValue调用,在这些版本中,构造如下语句进行验证:

直接利用成功:

其后,Struts2从2.3.29开始对isEvalExpression函数、SimpleNode类的isSequence函数做了修改,禁用了链式表达式,所有由ASTSequence类处理的ognl表达式都会抛出异常。

本漏洞利用模式失效。
** 2、S2-037漏洞 **
前阵子曝出的S2-037漏洞业内关注度比较高,也是一个远程执行漏洞。本漏洞发现者在漏洞利用上采用了一种新的模式,虽然能够绕过官方的过滤处理,不过仅使用037的绕过方式很难构造出可回显输出的语句。
** 3、ADLab最新研究漏洞 **
ADLab本次漏洞研究中,除了漏洞本身之外,在利用技术上也做了完美突破,能够绕过所有过滤处理,通杀2.1.0--2.5.1所有版本,达到执行任意系统命令的目的,并能够成功将执行命令的结果输出到浏览器页面中。

完美的漏洞利用方式细节,这里出于用户安全考虑,也不做过多阐述了。
在开启devMode情况下,本漏洞可影响Struts 2.1.0--2.5.1,通杀Struts2所有版本。
### 参考链接
* https://struts.apache.org/docs/s2-008.html
* https://cwiki.apache.org/confluence/display/WW/S2-037
* https://struts.apache.org/docs/devmode.html
全部评论 (1)