Java Struts2系列的XSS漏洞(S2-002)

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" 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-002" extends="struts-default">  
        <action name="login" class="com.drunkbaby.action.LoginAction" method="execute">  
            <result name="success">welcome.jsp</result>  
            <result name="error">index.jsp</result>  
        </action>  
    </package>  
</struts>

 

webapp 文件夾下

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"  
         pageEncoding="UTF-8"%>  
<%@ taglib prefix="s" uri="/struts-tags" %>  
  
<html>  
<head>  
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
    <title>S2-002</title>  
</head>  
<body>  
<h2>S2-002 Demo</h2>  
<s:url action="login" includeParams="all"></s:url>  
<s:a href="%{url}">click</s:a>  
</body>  
</html>

welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"  
         pageEncoding="UTF-8"%>  
<%@ taglib prefix="s" uri="/struts-tags" %>  
  
<html>  
<head>  
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  <title>S2-002</title>  
</head>  
<body>  
<p>Hello <s:property value="username"></s:property></p>  
</body>  
</html>

接着在 WEB-INF 下,web.xml

<!DOCTYPE web-app PUBLIC  
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  
 "http://java.sun.com/dtd/web-app_2_3.dtd" >  
  
<web-app>  
  <display-name>S2-002 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>

項目結構如圖,至此環境搭建完畢

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() 方法。

【----幫助網安學習,以下所有學習資料免費領!加vx:yj009991,備註 “博客園” 獲取!】

 ① 網安學習成長路徑思維導圖
 ② 60+網安經典常用工具包
 ③ 100+SRC漏洞分析報告
 ④ 150+網安攻防實戰技術電子書
 ⑤ 最權威CISSP 認證考試指南+題庫
 ⑥ 超1800頁CTF實戰技巧手冊
 ⑦ 最新網安大廠面試題合集(含答案)
 ⑧ APP客戶端安全檢測指南(安卓+IOS)

進入到了 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 行增加了如下修復代碼:

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

太雞肋,基本算不上修復。。。

0x05 小結

因爲是 XSS 漏洞,成因基本都是未進行 URL 編碼或某種轉碼,所以我們可以去看處理參數的過程進行漏洞挖掘。

S2-002 還是比較簡單的一個漏洞。

更多靶場實驗練習、網安學習資料,請點擊這裏>>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章