0x00 前言
补充一下Ognl表达式的相关的知识点。尽量调有用的知识点来进行记录。
Ognl:Object-Graph Navigation Language,表达式语言,Java能做的,都可以使用OGNL来完成,实际上相当于动态的Java代码执行。
0x01 Ognl 基础
1.三要素
- 表达式
- 所有的Ognl操作都是针对表达式解析后进行的。
- ROOT对象
- Ognl的操作对象
- 上下文环境
- Ongl的特定操作环境
2.OGNL表达式
通过#{}
的方式来执行,如果上下文是一个student的类,那么#{id}
就相当于student.getId()。通过此种方式就可以快速的调用上下文环境的结果。
3.OGNL表达式 %
被%{}
包括起来的会当做OGNL表示进行解析。
4.ONGL 表法式符号含义
0x02 Poc构造
通常测试poc:
%{1+1}
命令执行
@java.lang.Runtime@getRuntime().exec('calc')
补充知识
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对象。