Struts2 漏洞分析系列 - 初識 Struts2
00概述
Struts2是以MVC架構為基礎的WEB框架,通過WEB Filter的方式內嵌在WEB服務器中進行使用。
01搭建
1.搭建一個WEB項目
2.通過Maven引入Struts2的依賴
org.apache.struts struts2-core 2.0.5
3.添加Tomcat的啟動環境,配置部署的WAR包,并將Struts的依賴引入到WAR中
4.安裝Struts2的IDEA插件(方便后續配置高亮等,直接在Plugins搜struts2即可),在resources目錄下新建一個struts.xml(如果安裝了插件可以直接在新建時選擇XML Configuration File -> Struts Config進行創建)
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
5.在web.xml中添加struts2的filter
struts2 org.apache.struts2.dispatcher.FilterDispatcher
struts2 /*
index.jsp
上述步驟走完后,一個基本的struts2的環境就搭建完成了,后續只需要按需進行配置即可,完整的目錄結構如下:

02Struts2基本使用方式
2.0 action == struts2?
如果在學習Struts2相關漏洞之前有嘗試過當個腳本小子用過工具去攻擊存在ST2-xxx漏洞的網站,會發現實際上大部分情況下我們攻擊的都是.action后綴的文件。
那么是否.action后綴的文件就一定會對應著使用了Struts2?答案是至少目前看來是的,還沒有其他開源框架使用.action作為自己的一個標志,除非開發者自定義了Filter。
2.1 struts.xml
struts.xml是Struts2中的一項重要配置,所有與Struts2相關的配置都在這里進行。
默認模板如下:
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
2.1.0 include
在大型系統下必然會存在許多的配置,并且可能每個配置關聯的只是一組模塊,這時候如果全部寫在一個xml內未必顯得太過于臃腫,此時必然會考慮通過包含的語法進行解耦,Struts2也支持這種寫法,通過include引入其余xml文件。
比如我有一個user.xml:
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
后續我只需要通過include標簽將其引入到struts.xml中即可進行配置:
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
2.1.1 constant
constant標簽用于設置一些內置常量的值,比如我們可能了解得最多的devMode。
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
2.1.2 package
package標簽管理某個模塊下的所有action,可以將其類比為Java中的package。
屬性
描述
是否必需
name 是 包名,作為其它包應用本包的標記 extends 否 設置本包繼承其它包 namespace 否 設置包的命名空間 abstact 否 設置為抽象包 |
extends:當前包的繼承包,默認情況下需要繼承struts-default這個包。
namespace:命名空間,默認情況下是"",也可以理解為/,此時你的默認路由在根目錄下,如果設置為/user,則當前package下的所有action都是在user目錄下被匹配到。
2.1.3 action
action標簽用于設置某個動作類,并且在此處會根據name自動的定義路由,也就是我們常常看到的xxx.action。
屬性名稱
功能描述
是否必須
name 是 請求的Action名稱 class 否 Action處理類對應具體路徑 method 否 指定Action中的方法名 converter 否 指定Action使用的類型轉換器 |
name:當前action的名稱,后續設置路由也是根據name來設置的,比如這里的name是login,那么后續的路由則是login.action。
class:當前action對應的類,這個類相當于MVC中的M和C,也就是Model層和Controller層,因為具體業務處理代碼是在此類中體現的,并且此類也作為一個Bean類在后續調度中被使用。
method:將調用Action類的方法名,如果不指定的話默認調用的是Action的execute方法。
2.1.4 result
result標簽用于控制返回的視圖。
屬性名稱
功能描述
是否必須
name 否 對應Action返回邏輯視圖名稱,默認為success type 否 返回結果類型,默認為dispatcher |
name:設置返回值,當action class執行方法后返回對應值就會在此處根據name屬性進行匹配,匹配上了就返回對應視圖。
hello.jspindex.jsp
2.1.5 interceptors
Struts2中有一個攔截器的概念,類似于WEB容器中的Filter,但又有點不一樣,攔截器用于在每個請求到達真正的Action之前進行一系列的預處理,并在請求結束后進行一系列的銷毀動作。
Struts2內置了一系列的攔截器,并且會根據你的Action設置對應的攔截處理的操作,但是開發者依然可以自定義攔截器,通過interceptors標簽即可自定義攔截器。
2.1.6 示例
Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
welcome.jsp
上面是一個最基礎的例子,其設置了一個action,名為product,后續如果要訪問實際上就是通過product.action訪問它。
并且設置了class為com.javapoint.Product,這表明所有product.action的請求將交由Product#execute方法來處理(因為這里沒有通過method特指方法)。
最后設置了一個result標簽,此時當Product#execute返回success時則會返回welcome.jsp這個視圖,在welcome.jsp中可以用Struts特有的標簽來獲取上下文的對象信息,用于輸出定制化的界面。