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

全國(guó)咨詢電話

02389108633

關(guān)注官方微信

新型Tomcat Websocket內(nèi)存馬檢測(cè)與防護(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)無(wú)法檢測(cè)出該類型的內(nèi)存馬。為此,對(duì)該內(nèi)存馬的原理進(jìn)行了分析,并在此提出了一種檢測(cè)該內(nèi)存馬的思路,可以幫助安全人員檢測(cè)出此種類型內(nèi)存馬,從而降低業(yè)務(wù)系統(tǒng)安全隱患。



Websocket 內(nèi)存馬原理



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





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





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

首先要初始化一個(gè) WsServerContainer ,





通過(guò)掃描 classpath 下的帶注解的類并加入一個(gè) iterator  之中,





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





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



檢測(cè)思路

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

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





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





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





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

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

一個(gè)簡(jiǎn)單的 jsp 檢測(cè)腳本,訪問該 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" %>

<%

  // 通過(guò) 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, 打印所有注冊(cè)的 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, 對(duì)應(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")));

  }

%>



效果如下:





如果想要?jiǎng)h除一個(gè) ws 服務(wù),直接將該實(shí)體從 map 中移除即可,

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


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





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