freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Java OgnlMVEL and JEXL表达式注入漏洞成因及细节
2023-10-21 22:44:44

Preface

这里主要是对Java中的各种常见的表达式注入的各种类型和各种原理的一个较为全面的分析

Ognl(Object-Graph Navigation Language)

brief

背景

一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。

特点

OGNL使用Java反射内省来解决运行时应用程序的对象图

简单使用

下面是一些有关于Ognl语法的一些特别的语法

  • 类静态方法调用和值访问:@[类全名(包括包路径)]@[方法名|值名]

  • 访问OGNL上下文(OGNL context)和ActionContext

  • 可以直接通过new创建一个对象

  • 通过#符号进行容器变量的访问

  • 支持投影和选择

    选择:collection.{X YYY},其中X是一个选择操作符,后面则是选择用的逻辑表达式, 选择操作符有三类?^$

    投影:collection.{XXX},其中XXX是这个集合中每个元素的公共属性

  • Ognl的语法树形式

    • (expression)(constant) = value

    • (constant)((expression1)(expression2))

  • # . @的区别

    • 获取静态函数和变量的时候用@

    • 获取非静态函数用.号获取

    • 获取非静态变量用#获取

ActionContext对象解释

ActionContext是一个上下文对象,是一个以MAP为结构、利用键值对关系来描述对象中的属性以及值的对象

常见的作用域requestsessionapplication

三个独特的作用域

  • attr:保存着上面三个作用域的所有属性,如果有重复的则以request域中的属性为基准;

  • paramters:保存的是表单提交的参数;

  • VALUE_STACK:值栈,保存着valueStack对象,也就是说可以通过ActionContext访问到valueStack中的值;

detail

类似的提供一个可以解析Ongl表达式的例子

因为能够解析Ognl表达式的api有很多,我这里只选择了一种

@RequestMapping("/ognl")
@ResponseBody
public String OgnlTest(@RequestParam(required = false) String expression) {
    if (expression == null) {
        return "Send request with \"expression\" parameter!";
    }
    try {
        OgnlContext ognlContext = new OgnlContext();
        Ognl.getValue(expression, ognlContext, ognlContext.getRoot());
    } catch (Exception e) {
        return Util.printStack(e);
    }
    return "OK!";
}

在调用Ognl#getValue方法进行表达式的解析过程中

image-20231007125953797.png

将会通过调用parseExpression方法来进行类似于spel表达式的解析

在spel中是通过进行词法分析生成了一个token流,之后依据该tokens构建了一个AST的结构,进而使用spel中的API进行evaluate

而在Ongl中,在parseExpression方法中同样是构造了一个AST结构

image-20231007130530950.png

在ongl中表现为ASTChain类这个数据结构

将不同的语句抽象为一个一个Node结点,这些结点都是SimpleNode这个抽象类的实现类

image-20231007231830672.png

类似于方法调用封装为ASTMethod类结点,而构造方法封装为ASTCtor类结点

前面是解析Ognl表达式的过程,接下来就是根据得到的ASTChain进行evaluate,也就是在Ognl#getValue中的逻辑

image-20231007232302585.png

核心逻辑是循环的调用每一个结点的getValue方法,其中核心的逻辑是在每一个结点实现的getValueBody方法中

例如ASTCtor#getValueBody

image-20231008225127580.png

主要是通过Class.forName获取目标类

而对于方法的调用,主要是封装为ASTMethod对象,调用目标方法

image-20231008225536647.png

# 网络安全 # 网络安全技术
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录