0x00 前言
针对Struts2 系列漏洞进行记录,之前可能零零散散的看了一下,但是没有进行系统的记录,所以从头进行记录。
Demo是直接使用大佬们搭建好的,为了节约一下搭建环境的时间。
0x01 环境
Demo地址:https://github.com/xhycccc/Struts2-Vuln-Demo
配置好Tomcat之后启动:
0x02 漏洞复现
通过测试payload:%{1+1}
0x03 漏洞分析
1.调用链
getValue:333, Ognl (ognl)
getValue:192, OgnlUtil (com.opensymphony.xwork2.util)
findValue:244, OgnlValueStack (com.opensymphony.xwork2.util)
translateVariables:123, TextParseUtil (com.opensymphony.xwork2.util)
translateVariables:72, TextParseUtil (com.opensymphony.xwork2.util)
findValue:303, Component (org.apache.struts2.components)
evaluateParams:680, UIBean (org.apache.struts2.components)
end:450, UIBean (org.apache.struts2.components)
doEndTag:36, ComponentTagSupport (org.apache.struts2.views.jsp)
2.漏洞分析
入口是在username,因为我们的测试也是从username进行的。
调用this.component.end
通过调用evaluateParams来处理jsp的动态数据
解析nameValue:this.addParameter
调用TextParseUtil.translateVariables,也就是xwork2中的方法,这里就会针对ognl进行处理,那么也就是说如果找到了这个的调用位置,也就是发现了Ognl的相关漏洞
循环解析Ognl
![在这里插入图片描述](https://img-blog.csdnimg.cn/8c09d25f7f164aafa2c0285f7a5240c1.png
最终的调用位置在:getValue:192, OgnlUtil (com.opensymphony.xwork2.util),这里是直接调用了Ognl.getValue进行了ognl解析
0x04 修复方式
在2.04中,通过判断抛出了循环,不再进行解析
以上
补充知识
struts2
Struts2 是一个基于 MVC 模式的 Web 应用程序开发框架,其核心是一个前端控制器,它使用 Java Servlet 技术实现。Struts2 可以帮助开发人员更快地构建 Web 应用程序,同时提供了许多可重用的组件,如表单处理、数据验证、国际化、文件上传和数据库访问等。
Struts2 采用了多种设计模式来实现灵活性和可扩展性。例如,使用拦截器来处理应用程序的流程控制、消息传递和异常处理;使用配置文件来定义所有的 Action 和拦截器;使用标签库来生成 HTML 表单和页面元素等。
Struts2 具有以下特点:
-
面向对象:使用面向对象的编程技术,可构建高性能和高可靠性的 Web 应用程序。
-
灵活性:Struts2 提供了许多可重用的组件和灵活的配置选项,可根据需要进行扩展或定制。
-
易于使用:Struts2 使用简单明了的编码结构和清晰的文档,使开发人员可以更快地构建 Web 应用程序。
-
安全性:Struts2 支持身份验证和授权,可以帮助应用程序更好地保护用户的敏感信息。
-
高效性:Struts2 采用了多种技术来提高应用程序的性能,例如缓存、预编译和延迟加载等。
总体而言,Struts2 是一个成熟的、可靠的 Web 开发框架,已经广泛应用于许多企业级应用程序中。
S2 005
S2-005是指一种名为Apache Struts 2的开源Web应用程序框架中的漏洞。该漏洞允许攻击者通过提交恶意请求来执行任意代码,从而完全控制受影响的服务器。
该漏洞源于一个过滤器配置错误,这使得攻击者可以在Struts 2应用程序中注入OGNL (Object-Graph Navigation Language)表达式,这是一种强大的表达式语言,攻击者可以使用它来执行恶意代码。
许多版本的Struts 2都受到此漏洞的影响,因此组织和企业应该及时验证其系统是否存在此漏洞,并且及时更新和修补相关应用程序的漏洞。
Ognl
Ognl(Object-Graph Navigation Language,即对象图导航语言)是一个用于访问 Java 对象属性和方法的表达式语言。它可以被用于许多框架和应用中,如 Struts、Hibernate 和 JSTL。Ognl 通过使用点号(.)访问对象的属性和方法,而不需要调用 getter 和 setter 方法。此外,它还支持一些高级特性,如数组、集合、映射、正则表达式等。Ognl 语法简洁且易于学习,能够提高 Java 开发效率。Ognl(Object-Graph Navigation Language,即对象图导航语言)是一个用于访问 Java 对象属性和方法的表达式语言。它可以被用于许多框架和应用中,如 Struts、Hibernate 和 JSTL。Ognl 通过使用点号(.)访问对象的属性和方法,而不需要调用 getter 和 setter 方法。此外,它还支持一些高级特性,如数组、集合、映射、正则表达式等。Ognl 语法简洁且易于学习,能够提高 Java 开发效率。
以下是一个简单的 Ognl 使用示例:
import ognl.Ognl;
import ognl.OgnlException;
public class OgnlExample {
public static void main(String[] args) throws OgnlException {
User user = new User("John", 25);
// 获取对象属性的值
String name = (String) Ognl.getValue("name", user);
int age = (int) Ognl.getValue("age", user);
System.out.println("User name: " + name);
System.out.println("User age: " + age);
// 设置对象属性的值
Ognl.setValue("name", user, "Peter");
Ognl.setValue("age", user, 30);
System.out.println("User name: " + user.getName());
System.out.println("User age: " + user.getAge());
}
}
class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
在上面的示例中,我们创建了一个名为 User
的简单 Java 类,并使用 Ognl 获取和设置它的属性。在使用 Ognl.getValue()
方法获取属性值时,我们使用属性名 "name"
和 "age"
,分别获取 User
对象的名称和年龄。我们还可以使用 Ognl.setValue()
方法来设置 User
对象的名称和年龄。
注意:在使用 Ognl 时,必须导入 ognl.Ognl
和 ognl.OgnlException
类。
Ognl %和#的区别
在OGNL表达式中,%符号和#符号有不同的含义。
- %符号
%符号用于访问静态字段和方法。例如,假设有一个名为com.example.Person的类,并且它有一个静态字段name,则可以使用以下OGNL表达式来访问它:@com.example.Person@name
- #符号
#符号用于引用变量。变量可以在OGNL上下文中定义,并且可以在表达式中使用。例如,假设有一个名为person的变量,则可以使用以下OGNL表达式来引用它:#person
总结:%符号用于访问静态成员,#符号用于引用动态变量。
Ognl 表达式
OGNL(Object-Graph Navigation Language,对象图导航语言)是一种用于Java应用程序中访问对象图的表达式语言。OGNL允许开发者使用简单的表达式从Java对象中获取和设置属性、调用方法和操作集合等。
OGNL的语法类似于JavaScript和EL表达式,支持访问对象的属性、方法和索引,以及运算符和条件语句等。OGNL还支持访问静态类和字段,以及调用静态方法。
以下是一些常见的OGNL表达式示例:
- 获取对象属性:
user.name
- 调用对象方法:
user.getName()
- 访问集合元素:
list[0]
- 访问Map元素:
map['key']
- 表达式求值:
1 + 2 * 3
- 条件语句:
age >= 18 ? '成年人' : '未成年人'
- 调用静态方法:
@java.lang.Math@random()
在Java应用程序中,OGNL通常用于Web框架、ORM框架和模板引擎等技术中,以快速且简单地访问和操作Java对象。