本系列文章主旨在于介绍一些漏洞类型产生的基本原理,探索最基础的解决问题的措施。
关于什么是EL(Expression Language),不在这里详细叙述,可以参考 9 Expression Language (Release 7) 和 Overview of the EL - The Java EE 6 Tutorial。
EL确实给实现带来了很多方便,例如:在JSLT中,可以直接显示一个对象的一个属性:<c:out value=”person.name”/> , 使用Java代码就需要显示为:<%=HTMLEncoder.encode(((Person)person).getName())%>。不过,带来便利的同时,也带来了一些风险。
EL的主要功能有:
看到EL的这些功能,我们可能就知道,使用它是一件比较危险的事情,因为他可以读取或者写入数据,还可以动态调用公共的静态方法。EL注入主要是因为将不可信的数据传递给EL解释器,EL解释器将其中注入的一些恶意的代码解析并执行。而且,在一些框架(例如:SpringMVC)中EL标签被Evaluate两次,一个是应用服务器、另外一个就是Spring标签解析的实现。
例如:一个URL是:https://ww.test.com/info?msg=${applicationScope},对应的页面的代码中使用<spring:message text="" code="${param['msg']}"></spring:message>显示消息。由于msg的内容被Evaluate两次,所以会把applicaitonScope对象的toString的内容打印出来,如下:
{org.apache.catalina.jsp_classpath=/ home/test/ELInjection/target/ Test/WEB-INF/classes/: Test/WEB-INF/lib/aopalliance- 1.0.jar:/home/test/ELInjection/ target/Test/WEB-INF/lib/ commons-logging-1.1.1.jar ...
}
由于applicaitonScope对象中含有classpath、应用程序工作路径以及其他信息,这些信息可以被攻击者用来挖掘下一步攻击, 也可以通过注入${9999+1},如果查看结果显示为10000,那就可能存在EL注入。接着可以注入一些可以执行命令的串再试试,例如:
${"".getClass().forName("java.lang.Runtime").getMethods()[6].invoke("".getClass().forName("java.lang.Runtime")).exec("calc.exe")}
在进一步了解如何预防EL注入之前,首先需要了解哪些技术或者框架使用了EL,并且可能造成EL注入。
JSTL | JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。 |
OGNL | 对象导航图语言(Object Graph Navigation Language),简称OGNL,是应用于Java中的一个开源的表达式语言(Expression Language),它被集成在Struts2等框架中,作用是对数据进行访问,它拥有类型转换、访问对象方法、操作集合对象等功能。 |
MVEL | MVEL是一个功能强大的基于Java应用程序的表达式语言。 |
SPEL | Spring Expression Language(缩写为SpEL)是一种强大的表达式语言。在Spring产品组合中,它是表达式计算的基础。它支持在运行时查询和操作对象图,它可以与基于XML和基于注解的Spring配置还有bean定义一起使用。 |
EL注入攻击可能造成的危害如下:
可见EL注入的危害非常大,Struts2也经常因为ONGL而报出RCE相关的漏洞。
在使用这些技术之前,就需要小心,如何避免EL注入的问题。
如果有不妥之处,希望可以留言指出。谢谢!
参考:
https://www.reshiftsecurity.com/el-injection-primer-for-java-developers/
CWE-917 : Expression Language (EL) Injection - kiuwan - Kiuwan documentation