Struts2介绍

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

Struts2与Struts1关系:Struts2是Struts的下一代产品,是在Struts1和WebWork的技术基础上进行了合并的全新的Struts2框架
其全新的Struts2的体系结构与Struts1的体系结构差别巨大。

Struts2以WebWork为核心

Struts2=Struts1+WebWork

Struts2是Apache的产品。

Struts2是一个标准的MVC框架。JAVAWEB中的model2模式就是一个MVC模式。model2=Servlet+jsp+JavaBean

Struts2框架是在JAVAWEB开发中使用的。
使用Struts2框架,可以简化我们的web开发,并且降低程序的耦合度。

类似于Struts2框架的产品:Struts1、webwork、jsf(Sun提供)、SpringMVC都是MVC模式

Struts2环境配置

这里采用maven添加依赖的方式配置

这里选了一个最低版本的方便漏洞测试

image-20240510165534126

可以安装一个struts2插件方便高亮显示

image-20240510165817113

配置web.xml的过滤器和映射,配置可以参考官网:https://struts.apache.org/getting-started/how-to-create-a-struts2-web-application#our-first-application,不过过滤器可能不同版本的框架不一样需要自己选择,还可以从项目源码给的示例war包中的WEB-INF下的web.xml来参考

<display-name>Basic Struts2</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>

image-20240510190214572

解释一下各标签的含义,配得比较少顺便记录一下:

<display-name>:这是一个可选的标签,用于为 Web 应用提供一个显示名称。这个名称通常在部署时或通过应用服务器的管理界面展示。
<filter>:定义一个过滤器,它是 Java Servlet 规范的一部分,用于拦截进入 Servlet 容器的请求和响应。

<filter-name>:为过滤器指定一个名称,这里名称为 struts2。这个名称在整个应用中应该是唯一的,并且在后面定义 <filter-mapping> 时会被引用。
<filter-class>:指定过滤器的完整类名。在这个例子中,org.apache.struts2.dispatcher.FilterDispatcher 是 Struts2 框架的核心过滤器类,它负责拦截请求并分派给相应的 Action 对象处理。

<filter-mapping>:定义如何将过滤器映射到 Servlet 容器中的 URL 请求上。

<filter-name>:指定上面定义的过滤器的名称,这里引用了 struts2 过滤器。
<url-pattern>:定义过滤器将被应用于哪些 URL 请求。/* 是一个通配符,表示所有的 URL 请求都将被 struts2 过滤器处理。

<welcome-file-list>:定义应用的欢迎文件,当用户访问应用的根目录而没有指定具体页面时,Servlet 容器将提供这些文件。

<welcome-file>:指定欢迎文件的名称,这里为 index.jsp。这意味着当用户访问应用的根 URL 时,如 http://localhost:8080/YourApp/,Servlet 容器将自动提供 index.jsp 页面。

然后就是自己添加一个struts2.xml用来指定 URL、Java 类和视图页面(例如index.jsp)之间的关系,这里也参考上面官网的配置,文件路径为src/main/resources,dtd文件的版本也要和自己的框架版本对应

<?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" />
<!--所有的action要放在packages中,且要继承struts-default包,因为里面是该框架封装的东西-->
<package name="basicstruts2" extends="struts-default">
<!--name对应的是请求地址,class是请求处理的类-->
<action name="index">
<result>/index.jsp</result>
</action>
<!--result的name是Action类中返回的字符串,对应不同相应到不同页面-->
<action name="hello" class="action.HelloWorldAction" method="execute">
<result name="success">/HelloWorld.jsp</result>
</action>
</package>
</struts>

image-20240510191813662

struts.xml 文件的主要作用包括:

  1. 定义包(Packages):Struts 2 允许通过包的概念来组织和隔离不同的 Action 和结果类型。每个包可以有自己的命名空间,并且可以重用其他包中定义的类。
  2. 配置 Action:在 struts.xml 中,你可以定义 Action,包括 Action 的类、方法以及它们映射到的请求 URL。Action 映射可以是简单的路径映射,也可以是更复杂的参数映射。
  3. 结果(Result)映射:为每个 Action 定义可能的结果映射。结果可以是转发到另一个页面、重定向到另一个 URL,或者是自由格式的字符串。
  4. 拦截器(Interceptors)配置:Struts 2 使用拦截器来处理如身份验证、日志记录、事务管理等横切关注点。在 struts.xml 中,可以定义拦截器栈(Interceptor Stacks)和特定的拦截器。
  5. 异常处理:定义全局和操作级别的异常处理机制,允许你捕获和处理应用程序中的异常。
  6. 类型转换:配置如何将 HTTP 请求参数转换为 Action 属性的类型。
  7. 包含其他配置文件:可以使用 <include> 标签来包含其他配置文件,这有助于将配置分散到多个文件中,使主配置文件保持简洁。
  8. 常量和文本资源:定义可以在多个地方使用的常量,以及国际化的文本资源。
  9. 动态方法调用:允许你定义特定 Action 对应的多个方法,这些方法可以通过请求参数来动态调用。

写一个简单程序

现在按照上面的struts.xml的配置来写一个hellworld的程序:

package action;

import com.opensymphony.xwork2.Action;

public class HelloWorldAction implements Action {
@Override
public String execute() throws Exception {
System.out.println("Hello Struts2~~");
return SUCCESS;
}
}

目录结构如下:

image-20240510202619138

额这里配置时又有个坑,他的web目录下的有关struts2依赖的jar全都没有自动导入到WEB-INF/lib下面,会导致启动的出现过滤器异常的问题

image-20240510202443723

所以要在这里把右边的jar包都添加过去才行。

然后启动tomcat服务器即可、

难绷只能说又被坑惨了一次,访问路由是需要.action后缀的,不然就是资源未访问,难绷

image-20240510205435309

image-20240510205450490

要修改后缀可以在struts.xml中使用这个属性设置

<constant name="struts.action.extension" value=""/>

这样子可以去掉后缀,但后果是所有jsp文件都不解析了,只能使用不带后缀的路由,然后根目录访问就是404访问半天也找不到原因服了,就这样吧

image-20240510214235237

image-20240510214249703

不过这样看到后缀是action的路由就能很明显的判断出是status框架

S2-001远程代码执行漏洞

参考文章:https://anquanke.com/post/id/254808

S2-001的漏洞原理是模板文件(JSP)中引用了不合适的标签进行渲染,并且渲染的值是用户可控的,此时则达成了表达式注入的目的。

这篇文章从源码上去分析,十分详细,我这里就总结一下重点的地方

OGNL表达式

要先简单了解一下OGNL表达式是什么,因为该漏洞就是和该表达式渲染相关而产生的漏洞