1. 基本概念
Listener(监听器) 是 Java Web 应用中的组件,用于监听 Web 应用生命周期或作用域对象(如 Session、Request)的变化,并在事件发生时自动执行回调逻辑。
常见的 Listener 类型:
-
ServletContextListener:监听 Web 应用的启动和销毁
-
HttpSessionListener:监听 Session 的创建与销毁
-
ServletRequestListener:监听请求的创建与销毁
Listener 内存马 的原理:
-
在运行时动态注册一个恶意 Listener
-
借助 Listener 生命周期回调(例如请求创建)作为触发点
-
实现任意代码执行或请求劫持
ServletRequestListener 的生命周期
2. Listener 装载流程(开发者视角)
2.1 定义 Listener
1 | package com.example.memshell; |
2.2 配置 web.xml
1 | <listener> |
2.3 Tomcat 加载
-
启动时,Tomcat 解析
web.xml -
创建并注册
MyListener -
在应用启动/关闭时触发对应的回调方法
3. Tomcat Listener 加载流程(容器内部机制)
3.1 Web 应用启动
-
Tomcat 在解析
web.xml时,遇到<listener>节点 -
调用
StandardContext.addApplicationListener()注册
3.2 Listener 存储
-
Listener 被封装成
ApplicationListener对象 -
存放在
StandardContext.applicationListeners列表中
3.3 事件触发
-
当容器或作用域对象发生事件时,Tomcat 遍历 Listener 列表
-
调用对应回调方法(如
contextInitialized、requestDestroyed等)
4. 内存马实现机制
实现步骤:
-
定义恶意 Listener(例如请求时执行命令)
-
获取 StandardContext(与前两篇方法相同,通过反射)
-
调用 addApplicationListener() 注册恶意 Listener
-
等待事件触发,即可在请求到达时或 Session 创建时执行恶意逻辑
5. 示例代码(JSP Listener 内存马)
1 | <%@ page import="java.io.*" %> |
6. 触发步骤
-
上传 JSP 木马至目标服务器
-
访问 JSP 文件 → 动态注册恶意 Listener
-
触发事件:
-
请求到达时(
ServletRequestListener) -
或 Session 创建时(
HttpSessionListener)
-
-
恶意逻辑执行,例如命令执行或请求劫持
-
(可选)删除 JSP 文件,Listener 仍然存在
7. 总结
-
Listener 内存马 通过 事件回调 机制触发恶意逻辑
-
与 Servlet/Filter 内存马不同:
-
Servlet:绑定 URL,显式访问触发
-
Filter:请求链入口,所有请求都会过
-
Listener:事件驱动,被动触发,更加隐蔽
-
-
关键 API:
StandardContext.addApplicationListener() -
优势