# Java代码审计之Struts2-002(二)

**URL:** <https://forum.90sec.com/t/topic/1148>\
**Category:** 代码审计\
**Created:** [2020 年6 月 23 日 05:21 UTC](https://forum.90sec.com/t/topic/1148 "2020-06-23T05:21:35Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![mochazz](https://forum.90sec.com/user_avatar/forum.90sec.com/mochazz/32/2270_2.png) [@mochazz](https://forum.90sec.com/u/mochazz)\
发布日期： [2020 年6 月 23 日 05:21 UTC](https://forum.90sec.com/t/topic/1148/1 "2020-06-23T05:21:35Z")

</div>

本系列文章将详细分析 **Java** 流行框架 **Struts2** 的历史漏洞，今后关于 **Struts2** 新的漏洞分析，也将更新于 [Struts2-Vuln](https://github.com/Mochazz/Struts2-Vuln) 项目上。该系列仅是笔者初学 **Java代码审计** 的一些记录，也希望能够帮助到想学习 **Java代码审计** 的朋友 。如有任何问题，欢迎 **issue** 。分析文章均来自 [**个人博客**](https://mochazz.github.io) ，转载请注明出处。

## 漏洞概要

Struts2-002是一个 **XSS** 漏洞，该漏洞发生在 **\<s:url\>** 和 **\<s:a\>** 标签中，当标签的属性 **includeParams=all** 时，即可触发该漏洞。

漏洞影响版本： **Struts 2.0.0 - Struts 2.1.8.1** 。更多详情可参考官方通告：[https://cwiki.apache.org/confluence/display/WW/S2-002](https://cwiki.apache.org/confluence/display/WW/S2-002)

## 漏洞环境

Apache Tomcat/8.5.47+struts-2.0.8

下载地址：[http://archive.apache.org/dist/struts/binaries/struts-2.0.8-all.zip](http://archive.apache.org/dist/struts/binaries/struts-2.0.8-all.zip)

> **[vulhub/vulhub](https://github.com/vulhub/vulhub/tree/master/struts2/s2-001)**
>
> Pre-Built Vulnerable Environments Based on Docker-Compose - vulhub/vulhub

## 漏洞分析

从先前的文章，我们可以知道。当程序开始解析 **Struts** 标签时，会调用 **org.apache.struts2.views.jsp.ComponentTagSupport:doStartTag()** 方法。

 ![1](https://forum.90sec.com/uploads/default/original/2X/d/d85391cd04a1aa13680052c259a3d7cf8cc8f7c7.png)

由于我们这里处理的是 **\<s:url\>** 标签，所以这里用来处理标签的组件 **this.component** 为 **org.apache.struts2.components.URL** 类对象。我们跟进 **URL:start()** 方法。

 ![2](https://forum.90sec.com/uploads/default/original/2X/7/7e50b79eca8f45f4cf522fbdfc9e91f3477464c3.png)

在 **URL:start()** 方法中，我们看到当 **includeParams=all** 时，会调用 **mergeRequestParameters** 方法。

 ![3](https://forum.90sec.com/uploads/default/original/2X/a/aa7b2b71f313178d5218a03f0dede012c768267c.png)

在 **mergeRequestParameters** 方法中，程序会将 **this.req.getParameterMap()** 获得的键值对数据存入 **this.parameters** 属性。

 ![4](https://forum.90sec.com/uploads/default/original/2X/2/2db08dea64b2e0573638cff2b6227e4a34b545b5.png)

在 **mergeRequestParameters** 方法之后，依次是 **includeGetParameters、includeExtraParameters** 方法。 **includeGetParameters** 方法主要是将 **HttpRequest.getQueryString()** 的数据存入 **this.parameters** 属性，而 **includeExtraParameters** 方法则用来存入其它数据。

 ![5](https://forum.90sec.com/uploads/default/original/2X/e/e8cf35c6b30cc07fc113b57ed3a7037f35e3a02f.png)

最后会由 **URLHelper** 类处理 **this.parameters** 数据（将其拼接在URL中）并返回给用户，这也导致最终的 **XSS** 漏洞。

 ![6](https://forum.90sec.com/uploads/default/original/2X/0/0763e94ca8f0b70711a084c4720cee8f884f6c32.png)

来试下触发 **XSS** 漏洞：

```
http://localhost:8081/struts2-001/login.action?<script>alert(1);</script>=hello

```

 ![7](https://forum.90sec.com/uploads/default/original/2X/d/da7624e14db0cabcd43ec2d543410bf9a6aeb319.png)

在查看官方漏洞通告的时候，发现官方说的是 **includeParams** 设置成除了 **none** 以外值都能触发漏洞。本以为 **includeParams=get** 也能成功，但是实际测试发现并不能触发 **XSS** 漏洞。

 ![8](https://forum.90sec.com/uploads/default/original/2X/b/b2a20fabce76a0c0bfb910fc49f3cee956f75878.png)

主要原因在于：当 **includeParams=all** 时，会多执行一个 **mergeRequestParameters** 方法，而该方法会将 **this.req.getParameterMap()** 数据设置到 **this.parameters** 。如果 **includeParams=get** ，那么 **this.parameters** 中的数据，仅是来自 **this.req.getQueryString()** 。

 ![9](https://forum.90sec.com/uploads/default/original/2X/4/4299bf662d183344689d5224b824e463f8c30dfd.png)

而 **this.req.getParameterMap()** 获得的数据会主动进行 **URLdecode** ，但是 **this.req.getQueryString()** 不会。所以 **includeParams=get** 时，返回的数据是被 **URLencode** 过的，因此不能触发 **XSS** 漏洞。大家可以再通过下图示例代码加深理解：

 ![10](https://forum.90sec.com/uploads/default/original/2X/b/bef50a0fa1d2dec6116882cdb22b5cfd1ccf9242.png)
## 漏洞修复

下图右边为官方修复后的代码（左图struts-core-2.0.8，右图为struts-core-2.0.11.1），可以明显看到修复代码仅仅是将 **\<script\>** 替换成 **script** 了。然而这种修复方式明显可以绕过，例如：`<script 1>alert(1)</script>`

 ![11](https://forum.90sec.com/uploads/default/original/2X/3/3f8c71b546f03fdaf7ae4b388a904d7fa346a276.png)
## 参考

[Struts2框架: S2-002 漏洞详细分析](https://dean2021.github.io/posts/s2-002/)
