Struts2 漏洞分析系列 - 初识 Struts2

网站UI设计

  0x00 概述

  Struts2是以MVC架构为基础的WEB框架,通过WEB Filter的方式内嵌在WEB服务器中进行使用。

  0x01 搭建

  搭建一个WEB项目通过Maven引入Struts2的依赖<depencies> <depency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.0.5</version> </depency> </depencies>添加Tomcat的启动环境,配置部署的WAR包,并将Struts的依赖引入到WAR中安装Struts2的IDEA插件(方便后续配置高亮等,直接在Plugins搜struts2即可),在resources目录下新建一个struts.xml(如果安装了插件可以直接在新建时选择XML Configuration File -> Struts Config进行创建)<?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> </struts>在web.xml中添加struts2的filter<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>上述步骤走完后,一个基本的struts2的环境就搭建完成了,后续只需要按需进行配置即可,完整的目录结构如下:

  0x02 Struts2基本使用方式

  2.0 action == struts2?

  如果在学习Struts2相关漏洞之前有尝试过当个脚本小子用过工具去攻击存在ST2-xxx漏洞的网站,会发现实际上大部分情况下我们攻击的都是.action后缀的文件。

  那么是否.action后缀的文件就一定会对应着使用了Struts2?答案是至少目前看来是的,还没有其他开源框架使用.action作为自己的一个标志,除非开发者自定义了Filter。

  2.1 struts.xml

  struts.xml是Struts2中的一项重要配置,所有与Struts2相关的配置都在这里进行。

  默认模板如下:

  <?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></struts>2.1.0 include

  在大型系统下必然会存在许多的配置,并且可能每个配置关联的只是一组模块,这时候如果全部写在一个xml内未必显得太过于臃肿,此时必然会考虑通过包含的语法进行解耦,Struts2也这种写法,通过include引入其余xml文件。

  比如我有一个user.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="wwfy" exts="struts-default"> <action name="login" class="wwfy.user.LoginAction"> <!--省略Action其他配置--> </action> <action name="logout" class="wwfy.user.LogoutAction"> <!--省略Action其他配置--> </action> </package></struts>后续我只需要通过include标签将其引入到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> <include file="user.xml"/></struts>2.1.1 constant

  constant标签用于设置一些内置常量的值,比如我们可能了解得最多的devMode。

  <?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> <!--设置开发模式--> <constant name="struts.devMode" value="true"/> <!--设置编码形式为GB2312--> <constant name="struts.i18n.encoding" value="GB2312"/> <!--省略其他配置信息--></struts>2.1.2 package

  package标签管理某个模块下的所有action,可以将其类比为Java中的package。

  属性

  是否必需

  描述

  name

  是

  包名,作为其它包应用本包的标记

  exts

  否

  设置本包继承其它包

  namespace

  否

  设置包的命名空间

  abstact

  否

  设置为抽象包

  exts:当前包的继承包,默认情况下需要继承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属性进行匹配,匹配上了就返回对应视图。

  <result name="success">hello.jsp</result><result name="error">index.jsp</result>2.1.5 interceptors

  Struts2中有一个拦截器的概念,类似于WEB容器中的Filter,但又有点不一样,拦截器用于在每个请求到达真正的Action之前进行一系列的预处理,并在请求结束后进行一系列的销毁动作。

  Struts2内置了一系列的拦截器,并且会根据你的Action设置对应的拦截处理的操作,但是开发者依然可以自定义拦截器,通过interceptors标签即可自定义拦截器。

  <interceptors> <interceptor name="拦截器名" class="拦截器类"/> <interceptor-stack name="拦截器栈名"> <interceptor-ref name="拦截器名"> </interceptor-stack></interceptors>2.1.6 示例

  <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <package name="default" exts="struts-default"> <action name="product" class="com.javatpoint.Product"> <result name="success">welcome.jsp</result> </action> </package> </struts>上面是一个最基础的例子,其设置了一个action,名为product,后续如果要访问实际上就是通过product.action访问它。

  并且设置了class为com.javapoint.Product,这表明所有product.action的请求将交由Product#execute方法来处理(因为这里没有通过method特指方法)。

  最后设置了一个result标签,此时当Product#execute返回success时则会返回welcome.jsp这个视图,在welcome.jsp中可以用Struts特有的标签来获取上下文的对象信息,用于输出定制化的界面。

  本文由pzoro原创发布

  转载,请参考转载声明,注明出处: https://www.anquanke.com/post/id/254807

  安全客 - 有思想的安全新媒体

标签: 网站UI设计