JavaS2-002漏洞复现分析

admin 2026-03-03 05:05:01 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文复现分析了Struts2-002XSS漏洞,成因是s:url标签在includeParams=all时未对参数编码。文章通过源码调试定位到mergeRequestParameters方法的缺陷,并指出官方修复方案存在绕过风险。结论建议挖掘此类漏洞应重点关注参数处理过程中的编码缺失,具有较强的技术参考价值。 综合评分: 90 文章分类: 漏洞分析,WEB安全,代码审计


cover_image

Java S2-002 漏洞复现分析

蚁景网安

2026年2月26日 16:31 湖南

以下文章来源于蚁景网络安全 ,作者Drunkbaby

蚁景网络安全 .

致力于为你带来更实用的网络安全技术内容!

0x01 前言

复现一下 S2-002 的洞

0x02 S2-002

漏洞简介

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

漏洞影响版本

Struts 2.0.0 - Struts 2.1.8.1

0x03 环境搭建

  • • 如果不想手动搭建的话,环境我已经配好了 https://github.com/Drun1baby/JavaSecurityLearning/tree/main/JavaSecurity/Struts2/S2-002AndS2-006

因为 s2-002 的洞是一个 XSS,与处理的 Action 没有任何关系,所以这里我们只需要配置 .jsp 文件,以及 .xml 文件

  • • resources 文件夹下

struts.xml

<?xml version="1.0"&nbsp;encoding="UTF-8"?>

<!DOCTYPE&nbsp;struts&nbsp;PUBLIC
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
&nbsp; &nbsp; <packagename="S2-002"extends="struts-default">
&nbsp; &nbsp; &nbsp; &nbsp; <actionname="login"class="com.drunkbaby.action.LoginAction"method="execute">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <resultname="success">welcome.jsp</result>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <resultname="error">index.jsp</result>
&nbsp; &nbsp; &nbsp; &nbsp; </action>
&nbsp; &nbsp; </package>
</struts>
  • • webapp 文件夹下

index.jsp

<%@ page language="java"&nbsp;contentType="text/html; charset=UTF-8"
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pageEncoding="UTF-8"%>
<%@ taglib prefix="s"&nbsp;uri="/struts-tags"&nbsp;%>

<html>
<head>
&nbsp; &nbsp; <meta http-equiv="Content-Type"&nbsp;content="text/html; charset=UTF-8">
&nbsp; &nbsp; <title>S2-002</title>
</head>
<body>
<h2>S2-002&nbsp;Demo</h2>
<s:url action="login"&nbsp;includeParams="all"></s:url>
<s:a href="%{url}">click</s:a>
</body>
</html>

welcome.jsp

<%@ page language="java"&nbsp;contentType="text/html; charset=UTF-8"
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pageEncoding="UTF-8"%>
<%@ taglib prefix="s"&nbsp;uri="/struts-tags"&nbsp;%>

<html>
<head>
&nbsp; <meta http-equiv="Content-Type"&nbsp;content="text/html; charset=UTF-8">
&nbsp; <title>S2-002</title>
</head>
<body>
<p>Hello <s:property value="username"></s:property></p>
</body>
</html>

接着在 WEB-INF 下,web.xml

<!DOCTYPE&nbsp;web-app&nbsp;PUBLIC
&nbsp;"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
&nbsp;"http://java.sun.com/dtd/web-app_2_3.dtd"&nbsp;>

<web-app>
&nbsp; <display-name>S2-002 Example</display-name>
&nbsp; <filter>
&nbsp; &nbsp; <filter-name>struts2</filter-name>
&nbsp; &nbsp; <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
&nbsp; </filter>
&nbsp; <filter-mapping>
&nbsp; &nbsp; <filter-name>struts2</filter-name>
&nbsp; &nbsp; <url-pattern>/*</url-pattern>
&nbsp; </filter-mapping>
&nbsp; <welcome-file-list>
&nbsp; &nbsp; <welcome-file>index.jsp</welcome-file>
&nbsp; </welcome-file-list>
</web-app>

项目结构如图,至此环境搭建完毕

0x04 漏洞复现与分析

http://localhost:8080/?%22%3E%3Cscript%3Ealert(1)%3C/script%3E%3C%22

漏洞分析

之前自己也没有分析过 XSS 相关的漏洞,在最后我会做一个小结来思考一下如何自己挖掘出这个漏洞

我们先下一个断点在 org.apache.struts2.views.jsp.ComponentTagSupport#doStartTag() 方法处,开始调试

当在 JSP 文件中遇到 Struts2 标签 <s: 时,程序会先调用 doStartTag() 方法 ,并将标签中的属性设置到对应标签对象相应属性中。最后,在遇到 /> 结束标签的时候调用 doEndTag() 方法。

进入到了 index.jsp

跟进 this.component.start()

在 index.jsp 中 includeParams=all,往下看代码知道 88 行,跟进 mergeRequestParameters() 方法

在 includeParams=all 的情况下会调用 mergeRequestParameters() 将 Tomcat 处取来的参数,这里取到了我们输入的 payload,并且保存在 this.parameters 中

mergeRequestParameters() 方法运行完毕,往下是 includeGetParameters() 方法,也跟进去看一下;发现也是调用了 mergeRequestParameters(),同样是保存在了 this.parameters 中,不过这一次保存的是经过 url 编码的数据

继续往下,程序还调用了 includeExtraParameters() 方法,跟进;这里的意思是如果有额外的参数,会被保存进这里,然后再保存到 this.paramters

其实到这里漏洞出发点就来了,第一次调用 mergeRequestParameters() 方法的时候那一段参数是未经过 URL 编码的,从而产生了 XSS

在执行完毕 doStartTag() 方法之后,会去到 doEndTag() 方法,我们跟进 this.component.end()this.component 是 URL 类,所以也就是调用了 URL.end()

往下走,第 146 行,判断目前调度器(Dispatcher)的实例是否支持这一 Struts2 组件的行为,并且判断这一个请求是否需要 Struts2 组件调用某 Action 来处理;如果不需要调用 Action 处理,则直接进入 buildUrl() 的代码逻辑,如果需要 Action 来处理,会先去选择/调用 Action,再进行后续操作。

其实也就是 Struts2 运行的基本逻辑

此处因为我们定义了 action=login,所以进入到了 else 的代码逻辑,跟进 this.determineActionURL() 方法

determineActionURL() 方法先定位到了对应的 action,再进行 buildUrl() 的操作,跟进 buildUrl()

再跟进

此时的 params 即将会被拿去拼接,造成触发 XSS 漏洞

具体拼接是在 115 行的 buildParametersString() 方法,跟进再跟进

至此,漏洞分析结束

漏洞修复

修改 pom.xml,将 Struts2 版本提升至 2.0.11(这是根据公告的,其实并没有真正解决漏洞)

经过对 2.0.11.1 的代码阅读,在 UrlHelper 类 buildUrl() 方法里,第 136 行增加了如下修复代码:

&nbsp;// link是最终的生成的url
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;for(result = link.toString();
&nbsp; &nbsp; &nbsp; &nbsp; result.indexOf("<script>") >&nbsp;0;
&nbsp; &nbsp; &nbsp; &nbsp; result = result.replaceAll("<script>",&nbsp;"script")) {
&nbsp; &nbsp; &nbsp; &nbsp; }

太鸡肋,基本算不上修复。。。

0x05 小结

因为是 XSS 漏洞,成因基本都是未进行 URL 编码或某种转码,所以我们可以去看处理参数的过程进行漏洞挖掘。

S2-002 还是比较简单的一个漏洞。

学习网安实战课程,戳“阅读原文”


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:蚁景网安 《Java S2-002 漏洞复现分析》

评论:0   参与:  0