EL 表达式注入

1、EL 概述

表达式语言(Expression Language) 简称 EL,是 Java EE(尤其是 JSP 技术)中用来在页面中简化访问 Java 对象、属性、集合和方法的一种语法。它的主要作用是取代 JSP 页面中复杂的 <%= ... %> 表达式,让 JSP 页面更简洁、可读性更高。

1.1 EL 基本语法

要先通过 page 标签设置不忽略 EI 表达式

语法:

EL 表达式使用 ${} 或 #{} 语法。

在 JSP 中我们可以如下写:

而 JSP 当中有四大域,它们分别是:

  • page:当前页面有效
  • request:当前请求有效
  • session:当前会话有效
  • application:当前应用有效

el 表达式获取数据,会依次从这 4 个域中寻找,直到找到为止。而这四个域对象的作用范围如下图所示。

img

例如: ${brands},el 表达式获取数据,会先从 page 域对象中获取数据,如果没有再到 requet 域对象中获取数据,如果再没有再到 session 域对象中获取,如果还没有才会到 application 中获取数据。

2、EL 表达式注入漏洞

2.1 通用 POC:

2.2 简单漏洞利用

img

这种场景几乎不会遇到,也没有哪个开发者傻乎乎的让我们直接从外部控制 JSP 页面中的 EL 表达式。

2.3 简单的漏洞场景(CVE-2011-2730)

2.3.1 漏洞复现

首先创建一个 spring 项目,构建漏洞场景:

目录结构:

img

VulnController.java

spring-servlet.xml

web.xml

index.jsp

result.jsp

pom.xml

之后使用 maven 进行构建 .war 包用于 tomcat 运行。

这里使用 maven 时遇到一个 SSL 证书验证的问题,这里更改配置文件 setting.xml 禁用验证。

将以上文本复制到 C:\Users\<用户名>\.m2\settings.xml 文件中,之后执行 maven 就可以了

img

部署 Tomcat 服务器:

img

img

img

img

2.3.2 漏洞原理

命令执行PoC如下:

正常情况下为:

这里使用 message 标签,text 属性用 el表达式从请求参数中取值,这样当访问

${applicationScope} 这段字符串会被当做 el表达式被执行,而不是作为字符串直接显示在页面上,我们改变提交的 el表达式,就可以获取我们需要的信息了,这就达到了 el表达式注入的效果。

3、EL表达式的EXP与基础绕过

3.1 基础 EXP

3.2 利用 ScriptEngine 调用 JS 引擎绕过

同 SpEL 注入中讲到的

ScriptEngineExec.java

利用 Unicode 编码绕过

对可利用的 PoC 进行全部或部分的 Unicode 编码都是 OK 的:

利用八进制编码绕过

JohnFord 师傅的脚本

4、 防御方法

  • 尽量不使用外部输入的内容作为 EL 表达式内容;

  • 若使用,则严格过滤EL表达式注入漏洞的 payload 关键字;

  • 如果是排查 Java 程序中 JUEL 相关代码,则搜索如下关键类方法:

    • javax.el.ExpressionFactory.createValueExpression()
    • javax.el.ValueExpression.getValue()

参考:

java—-EL表达式:

https://blog.csdn.net/pan_junbiao/article/details/88567466

https://www.runoob.com/jsp/jsp-expression-language.html

Spring框架标签EL表达式执行漏洞分析(CVE-2011-2730) – lupin

https://www.vuln.cn/6484