Struts2 Ognl setValue 触发方式

0x00 前言

一直被Ognl卡着,主要描述了Ognl setValue poc触发的原理和方式。

0x01 环境

  • ognl-2.6.11

1.Demo

Map context = new HashMap();
Ognl.setValue("(\"@java.lang.Runtime@getRuntime().exec(\'calc\')\")(a)(b)",context,"");

0x02 原理

如果在Ognl中出现(a)(b)这样子子的解析内容的时候,会按照先解析a,再将a的结果给b,并且当做一个新的表达式进行解析。当然漏洞利用只在第一步,解析a。

有一个问题就是为什么 Ognl.setValue("(\"@java.lang.Runtime@getRuntime().exec(\'calc\')\")(a)(b)",context,"");这个poc可以,这个pocOgnl.setValue("(\"@java.lang.Runtime@getRuntime().exec(\'calc\')\")(a)",context,"");却不行。

看了很多文章都没有说清楚,现在来进行解析。

1.无法执行解析

首先先来看Ognl.setValue("(\"@java.lang.Runtime@getRuntime().exec(\'calc\')\")(a)",context,"");

关键点在:\ognl-2.6.11.jar!\ognl\ASTEval.class
在这里插入图片描述解析完之后,就会调用node.setValue

在这里插入图片描述
接着调用:setValueBody,这里直接-2,也就是说这里是没有办法处理两层的AST树
在这里插入图片描述
恰好@java.lang.Runtime@getRuntime().exec会被拆分成:@java.lang.Runtime@getRuntime()和exec。那么就只能实例化前面,无法进行后面的内容。

所以通过(a)(b)的方式没有办法执行。

2.可利用解析

接着来看(a)(b)©,同样的位置进入getValue

在这里插入图片描述

接着到比较关键的位置:getValueBody,在这里调用的是:result = node.getValue(context, source);

在这里插入图片描述

可以看到在getValueBody中的循环是-1,也就是说可以遍历到所有的节点。

在这里插入图片描述
所以只有(a)(b)©才可以触发目标

以上

补充知识

struts2

Struts2 是一个基于 MVC 模式的 Web 应用程序开发框架,其核心是一个前端控制器,它使用 Java Servlet 技术实现。Struts2 可以帮助开发人员更快地构建 Web 应用程序,同时提供了许多可重用的组件,如表单处理、数据验证、国际化、文件上传和数据库访问等。

Struts2 采用了多种设计模式来实现灵活性和可扩展性。例如,使用拦截器来处理应用程序的流程控制、消息传递和异常处理;使用配置文件来定义所有的 Action 和拦截器;使用标签库来生成 HTML 表单和页面元素等。

Struts2 具有以下特点:

  1. 面向对象:使用面向对象的编程技术,可构建高性能和高可靠性的 Web 应用程序。

  2. 灵活性:Struts2 提供了许多可重用的组件和灵活的配置选项,可根据需要进行扩展或定制。

  3. 易于使用:Struts2 使用简单明了的编码结构和清晰的文档,使开发人员可以更快地构建 Web 应用程序。

  4. 安全性:Struts2 支持身份验证和授权,可以帮助应用程序更好地保护用户的敏感信息。

  5. 高效性: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.Ognlognl.OgnlException 类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王嘟嘟_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值