记录黑客技术中优秀的内容,传播黑客文化,分享黑客技术精华

Struts2 漏洞分析系列 - 初识 Struts2

2021-11-09 18:28

 

0x00 概述

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

 

0x01 搭建

  1. 搭建一个WEB项目
  2. 通过Maven引入Struts2的依赖
    <dependencies>
    <dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-core</artifactId>
    <version>2.0.5</version>
    </dependency>
    </dependencies>
  3. 添加Tomcat的启动环境,配置部署的WAR包,并将Struts的依赖引入到WAR中
  4. 安装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>
  5. 在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" extends="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包名,作为其它包应用本包的标记
extends设置本包继承其它包
namespace设置包的命名空间
abstact设置为抽象包

extends:当前包的继承包,默认情况下需要继承struts-default这个包。

namespace:命名空间,默认情况下是"",也可以理解为/,此时你的默认路由在根目录下,如果设置为/user,则当前package下的所有action都是在user目录下被匹配到。

2.1.3 action

action标签用于设置某个动作类,并且在此处会根据name自动的定义路由,也就是我们常常看到的xxx.action。

属性名称是否必须功能描述
name请求的Action名称
classAction处理类对应具体路径
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" extends="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特有的标签来获取上下文的对象信息,用于输出定制化的界面。


知识来源: https://www.anquanke.com/post/id/254807

阅读:55153 | 评论:0 | 标签:漏洞 分析

想收藏或者和大家分享这篇好文章→复制链接地址

“Struts2 漏洞分析系列 - 初识 Struts2”共有0条留言

发表评论

姓名:

邮箱:

网址:

验证码:

黑帝公告 📢

永久免费持续更新精选优质黑客技术文章Hackdig,帮你成为掌握黑客技术的英雄

广而告之 💖

标签云 ☁