1、环境搭建
(1)打开EMSystemDO项目,设置Modules的web.xml文件路径,默认web路径为webcontent
(2)创建Department为EMSystemDO的war,设置Libraries的lib路径为项目lib路径
(3)使用mysql数据库,创建ssh_employee数据库,填写数据库登录用户名密码,无需导入sql语句加载启动项目时会自动导入
(4)设置Tomcat基本信息,启动项目进入首页
2、漏洞复现
使用Struts2检测工具对如下目标URL进行漏洞探测,发现检测到了该系统存在S2-045漏洞。
进一步使用S2-045的POC利用,发现成功执行了命令:
3、漏洞分析
(1)Struts2在dispatch类在封装request的时候做了一次content-type校验,随后如果符合条件则直接触发613行代码
(2)继续追踪到MultiPartRequestWrapper方法,发现在40行调用了parse方法
(3)进入parse方法,追踪76行,出现异常,调用buildErrrorMessagee
(4)继续往下追踪,发现调用了findText方法,这是一个敏感点,用来解析和执行表达式的方法
(5)继续向下追踪,分析323行代码为关键代码,调用了getDeaultMessage方法
(6)继续往下追踪,发现397行代码调用了BuildMessageFormat方法,这个方法中第一个参数调用了TextParseUtil.translateVariablesfa方法解析表达式
(7)最后就是具体的执行表达式的语法代码,第63行代码执行完就成功触发漏洞
此漏洞的原理是content-type内容出现异常触发了表达式的执行。
工具发送的攻击payload为如下内容:
content-type:test multipart/form-data %{#[email protected]@DEFAULT_MEMBER_ACCESS,@java.lang.Runtime@getRuntime().exec('whoami')}; boundary=AaB03x
4、修复方案
升级到Struts2.3.32版本,该版本禁止了异常的信息可执行OGNL表达式。
修复版本相关代码:
if (LocalizedTextUtil.findText(this.getClass(), errorKey, getLocale(), null, new Object[0]) == null) {
return LocalizedTextUtil.findText(this.getClass(), "struts.messages.error.uploading", defaultLocale, null, new Object[] { e.getMessage() });
} else {
return LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null, args);
}
原文始发于微信公众号(ZackSecurity):【Java框架审计】Struts2框架S2-045漏洞分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论