Skip to content

Latest commit

 

History

History
72 lines (52 loc) · 3.93 KB

ognl.md

File metadata and controls

72 lines (52 loc) · 3.93 KB

对象导航图语言(OGNL)注入

0x00 Introduction

OGNL (Object-Graph Navigation Language)即对象导航图语言,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。这样可以更好的取得数据。

OGNL三要素(也就是核心函数的三个参数):

  • 表达式(Expression) 表达式是整个OGNL的核心,所有的OGNL操作都是针对表达式的解析后进行的。表达式会规定此次OGNL操作到底要干什么。因此,表达式其实是一个带有语法含义的字符串,这个字符串将规定操作的类型和操作的内容。 OGNL支持大量的表达式语法,不仅支持“链式”描述对象访问路径,还支持在表达式中进行简单的计算,甚至还能够支持复杂的Lambda表达式等。
  • Root对象(Root Object) OGNL的Root对象可以理解为OGNL的操作对象。当OGNL表达式规定了“干什么”以后,我们还需要指定对谁干。OGNL的Root对象实际上是一个Java对象,是所有OGNL操作的实际载体。这就意味着,如果我们有一个OGNL的表达式,那么我们实际上需要针对Root对象去进行OGNL表达式的计算并返回结果。
  • 上下文环境(Context) 有了表达式和Root对象,我们已经可以使用OGNL的基本功能。例如,根据表达式针对OGNL中的Root对象进行“取值”或者“写值”操作。 不过,事实上,在OGNL的内部,所有的操作都会在一个特定的数据环境中运行,这个数据环境就是OGNL的上下文环境(Context)。说得再明白一些,就是这个上下文环境(Context)将规定OGNL的操作在哪里干。

推荐阅读: 表达式引擎--OGNL

0x01 危险函数

Ognl

例子:

public class Main {

    public static void main(String[] args) throws OgnlException {

        User user = new User();
        user.setId(1);
        user.setName("downpour");

        // 创建上下文环境
        Map context = new HashMap();
        context.put("introduction", "My name is ");

        // 测试从Root对象中进行表达式计算并获取结果
        Object name = Ognl.getValue(Ognl.parseExpression("name"), user);
        System.out.println(name.toString());

        // 测试从上下文环境中进行表达式计算并获取结果
        Object contextValue = Ognl.getValue(Ognl.parseExpression("#introduction"), context, user);
        System.out.println(contextValue);
        // 测试同时从将Root对象和上下文环境作为表达式的一部分进行计算
        Object hello = Ognl.getValue(Ognl.parseExpression("#introduction + name"), context, user);
        System.out.println(hello);

        // 对Root对象进行写值操作
        Ognl.setValue("group.name", user, "dev");
        Ognl.setValue("age", user, "18");

        System.out.println(user.getGroup().getName());

    }
}

Struts

OGNL表达式注入漏洞总结 中总结了解析OGNL的函数,代码审计可以重点关注。

Ref