Struts2-002 XSS漏洞浅析

阅读量    76775 |

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

 

一、原理

(一)概述

参见官方通告,特定版本的Apache Struts中的<s:url><s:a> 标签会引发XSS漏洞。

读者范围 所有Struts 2开发者
漏洞影响 客户端恶意代码注入
影响程度 重要
修复建议 更新至Struts 2.2.1
受影响的版本 Struts 2.0.0 – Struts 2.1.8.1

(二)原理

在返回的页面被渲染时,<s:url><s:a> 标签存在一定的可能性被注入未被合适转义的参数值。如下面的场景:

  • 一个 <s:a>标签被建立时,其中的参数值可以注入一个未被转义的双引号,如此则可以通过转义<href>标签注入生成的HTML。
  • includeParams 的值被设为非”none”时, <s:url><s:a> 标签未能转义<sc ript>标签,此时相应的JSP/action可能会被恶意的GET 参数破坏,例如http://localhost/foo/bar.action?<sc ript>alert(1)</sc ript>test=hello

 

二、调试

(一)环境搭建

因为要修改源码,短浅的想了想无法直接使用拿来主义,需要自己动手搭建(参考此链接),可在官网下载Tomcat,然后从此处中下载所需要的struts2,。

然后新建Project,Use Library中选择下载好的Struts2的lib。

进入Project Structure->Artifacts,点击下图红框中的那个选项,点击后会成为下图的样子。

接下来准备相关代码文件,首先src下新建struts.xml如下,

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <package name="S2-001" extends="struts-default">
        <action name="login" class="com.demo.action.LoginAction">
            <result name="success">welcome.jsp</result>
            <result name="error">index.jsp</result>
        </action>
    </package>
</struts>

接下来修改web.xml如下,

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
    <display-name>S2-001 Example</display-name>
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

选择Build->Build Project。

若正常则点击run,会有如下窗口。

(二)复现

修改Tomcat Server的URL配置,

run,可得,

可见XSS漏洞复现成功。

(三)调试

接下来以debug模式运行Tomcat Server,

可见可以在doStartTag处断下。

此时点击调用栈,也可以查看jsp内的流程了,

环境应该好了,可以准备调试Tomcat了。

由之前的学习可知,Struts开始解析jsp里的标签时,会调用ComponentTagSupport.doStartTag(),

此时的compnent为URL类,对应jsp里的url。

跟进this.component.start(),

可以看出,这里会将参数includeParams提取出来,为下面的流程做准备,

接下来会进行匹配,此处我们设置的includeParams值为all,故而会进入mergeRequestParameters(),

先看看 this.request.getParameterMap(),

多级步入之后,发现是从Request中提取参数,

跟进mergeRequestParameters,

这个函数名已经表示了它的功能,大概就是合并请求的各个参数,

跟进之,此时的Map mergedParams 的size为1,值为<sc ript>alert("1");</sc ript> -> 1,这时可以看到程序在读取了参数后,迭代添加到parameters里面去,

步出后,parameters的size为1,

接下来进入includeGetParameters,

这里能看到一点不同,

就是这里的query是urlencode之后的形式,

includeGetParameters这个函数的名字也告诉了我们它的功能,应该是将GET参数也添加进来。

解析标签,还需要调用doEndTag,

跟进end,

此处的一个关键点是determineActionURL,从函数名可以大致猜出,此函数是确定一个action对应出的url的,跟进,

这里面先将login.action的名字添加进去,接下来有一个buildParametersString函数,

因为在determineActionURL内,所以不难猜出这个函数的功能即是将url尾部的参数确定下来,跟进,

走到添加参数的地方,

current是未经url编码的,next是经过url编码的,其间要加一个连接符(或曰分隔符),

最终效果,

步出,

回到URL.end,

接下来就是将url输出。

另外,includeParameters必须为all,不能像官方通告里那样不为none即可,因为从调试过程中我们可以观察到,

若includeParameters为get,则只会进行一次includeGetParameters,而缺少if all分支中的mergeQequestParameters部分,且在刚才的调试过程中我们看到,includeGetParameters添加进来的参数是url编码过的,要想让页面上有<sc ript>xxxx</sc ript>的字符,还是得有if all 分支中独立的mergeQequestParameters的函数。

 

三、收获与启示

参考链接

环境搭建1

环境搭建2

https://www.cnblogs.com/twosmi1e/p/14134511.html

https://dean2021.github.io/posts/s2-002/

https://lanvnal.com/2021/01/05/s2-002-lou-dong-fen-xi/

https://cwiki.apache.org/confluence/display/WW/S2-002

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多