丁香五月激情综合国产,国产亚洲精品美女久久久m,国产亚洲av在线,国产成人综合野草

全國咨詢電話

02389108633

關(guān)注官方微信

新型Tomcat Websocket內(nèi)存馬檢測與防護(hù)思路探究

近期,看到網(wǎng)上有安全研究人員發(fā)布了一篇文章,描述了一款在Tomcat的全新內(nèi)存馬,地址為:https://www.iculture.cc/forum-post/19128.html,該內(nèi)存馬基于Websocket協(xié)議,有別于目前已知常見的filter型內(nèi)存馬、servlet型內(nèi)存馬,該類型的網(wǎng)馬從形式上還有功能上都是非常新穎的,且根據(jù)描述,目前常規(guī)的內(nèi)存馬掃描工具(如 Memshell Scanner)無法檢測出該類型的內(nèi)存馬。為此,對該內(nèi)存馬的原理進(jìn)行了分析,并在此提出了一種檢測該內(nèi)存馬的思路,可以幫助安全人員檢測出此種類型內(nèi)存馬,從而降低業(yè)務(wù)系統(tǒng)安全隱患。



Websocket 內(nèi)存馬原理



Tomcat服務(wù)器在啟動時會通過 WsSci 中的 WsServerContainer 將 classpath 注解下帶有 @ServerEndpoint 的類加入到 Websocket 服務(wù)中。如:





通過調(diào)試可以看到添加位置如下:





對該段代碼進(jìn)行分析,注冊websocket服務(wù)步驟如下,

首先要初始化一個 WsServerContainer ,





通過掃描 classpath 下的帶注解的類并加入一個 iterator  之中,





然后遍歷該列表,針對每個元素,然后創(chuàng)建一個 ServerEndpointConfig,然后通過 addEndpoint 將該類加入到 Websocket服務(wù)中。





至此,就將一個 ws 節(jié)點加入的服務(wù)中,根據(jù)這個思路,攻擊者也可以利用這種方式在運行時動態(tài)注入 ws 節(jié)點,注入的思路與此一致。



檢測思路

既然是內(nèi)存馬,那在內(nèi)存中肯定會有實體,所以只要找到存儲該實體的位置,就能檢測出此類內(nèi)存馬。

下面通過動態(tài)調(diào)試分析該實體的具體存儲位置,前面提到,最終是通過 addEndpoint 函數(shù)將該內(nèi)存馬實體加入到 ws 服務(wù)中,于是跟進(jìn)該函數(shù),





在 addEndpoint 中通過 (WsServerContainer.ExactPathMatch)this.configExactMatchMap.put(path,newMatch) 加入到一個名為 configExactMatchMap 的 Map 之中,進(jìn)一步查看該成員變量定義:





是一個 Map 的類型,通過調(diào)試可知,該 map 的 key 就是對應(yīng) ws 服務(wù)的 url, 后面的 WsServerContainer.ExactPathMatch 則存放了 ws 服務(wù)的實體,該類定義如下:





其中的 config 變量就是之前掃描注解時生成的實體類。

于是,檢測思路就呼之欲出了:找到對應(yīng) context 的 configExactMatchMap, 里面保存了所有注冊的 ws 服務(wù),每個服務(wù)就是該 map 中的一個元素。

一個簡單的 jsp 檢測腳本,訪問該 jsp 就能打印出所有的 ws 服務(wù)。



<%@ page import="org.apache.tomcat.websocket.server.WsServerContainer" %>

<%@ page import="javax.websocket.server.ServerContainer" %>

<%@ page import="java.lang.reflect.Field" %>

<%@ page import="java.util.Map" %>

<%@ page import="java.util.Set" %>

<%@ page import="java.util.Iterator" %>

<%@ page import="javax.websocket.server.ServerEndpointConfig" %><%-- Created by IntelliJ IDEA. --%>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%

  // 通過 request 的 context 獲取 ServerContainer

  WsServerContainer wsServerContainer = (WsServerContainer) request.getServletContext().getAttribute(ServerContainer.class.getName());

  // 利用反射獲取 WsServerContainer 類中的私有變量 configExactMatchMap

  Class obj = Class.forName("org.apache.tomcat.websocket.server.WsServerContainer");

  Field field = obj.getDeclaredField("configExactMatchMap");

  field.setAccessible(true);

  Map configExactMatchMap = (Map) field.get(wsServerContainer);

  // 遍歷configExactMatchMap, 打印所有注冊的 websocket 服務(wù)

  Set keyset = configExactMatchMap.keySet();

  Iterator iterator = keyset.iterator();

  while (iterator.hasNext()){

    String key = iterator.next();

    Object object = wsServerContainer.findMapping(key);

    Class wsMappingResultObj = Class.forName("org.apache.tomcat.websocket.server.WsMappingResult");

    Field configField = wsMappingResultObj.getDeclaredField("config");

    configField.setAccessible(true);

    ServerEndpointConfig config1 = (ServerEndpointConfig)configField.get(object);

    Class clazz = config1.getEndpointClass();

    // 打印 ws 服務(wù) url, 對應(yīng)的 class

    out.println(String.format("websocket name:%s,  websocket class: %s", key, clazz.getName()));

  }

  // 如果參數(shù)帶name, 刪除該服務(wù),名字為name參數(shù)值

  if(request.getParameter("name")!= null){

    configExactMatchMap.remove(request.getParameter("name"));

    out.println(String.format("delete ws service: %s", request.getParameter("name")));

  }

%>



效果如下:





如果想要刪除一個 ws 服務(wù),直接將該實體從 map 中移除即可,

configExactMatchMap.remove(request.getParameter("name"));


通過該 jsp 就是在后面加入 ?name=websocket服務(wù)名字即可:





再此訪問檢測工具,該服務(wù)已經(jīng)刪掉: