Apache Struts2存在远程代码执行漏洞,使用恶意的Content-Disposition值或者使用不合适的Content-Length头将payload传递给存在漏洞的服务器,将导致任意代码执行漏洞

漏洞分析

本次漏洞与S2-045(CVE-2017-5638)极其的相似,S2-046与S2-045都是在请求中构造错误的数据,触发struts2的异常处理机制(buildErrorMessage),而buildErrorMessage又会将报错信息中的ognl表达式进行执行,从而产生了漏洞

但不同的是S2-045是通过错误的Content-Type字段,而S2-046利用的则是错误的上传文件信息

因此这里着重讲一下S2-046与S2-045的不同之处。关于最终执行代码的执行点,二者是完全一样的,因此可以参考我之前的分析文章,在这里就不详细说明了

S2-046漏洞的poc如下

lQSSDs.png

从poc中可见,构造了一个含有payload的上传文件名,并且文件名中含有”\x00”

我们首先在StrutsPrepareFilter中doFilter方法中下断,执行poc并发送本次漏洞的利用请求

lMzvvQ.png

上图可见,程序执行到StrutsPrepareFilter中doFilter方法,doFilter方法中,程序将执行prepare.wrapRequest以进行request处理分支

跟入prepare.wrapRequest

lMzzuj.png

在prepare.wrapRequest中,调用dispatcher.wrapRequest对request进行处理

lQSi5V.png

见上图红框处的if分支。当content-type为”multipart/form-data”时进入该if分支,在该if分支中将调用MultiPartRequestWrapper生成一个名为request的实例

继续跟入MultiPartRequestWrapper类,进入其构造方法MultiPartRequestWrapper,见下图

lQSA8U.png

可见request请求被传入上图84行中parse方法中

继续跟入parse方法

lQSkCT.png

上图红框处,可见程序使用processUpload方法处理上传请求

跟入processUpload方法

lQSE2F.png

从上图可见,processUpload方法调用processFileField方法对item进行处理,而item是上传的文件信息

跟入processFileField

lQSeKJ.png

processFileField将会处理上传的文件信息

继续跟入getName方法

lQSCEq.png

getName方法调用Streams.checkFileName处理文件名,而文件名正是我们构造的payload

跟入checkFileName

lMzjgg.png

checkFileName会验证fileName参数中是否存在”\u0000”,很显然,我们的payload中构造了这个字段,程序会因此抛出异常

之后的异常处理以及代码执行步骤,与S2-052完全一致,这里不详细说明了