一种全新的内存马

VSole2022-12-13 10:56:20

前言

WebSocket是一种全双工通信协议,即客户端可以向服务端发送请求,服务端也可以主动向客户端推送数据。这样的特点,使得它在一些实时性要求比较高的场景效果斐然(比如微信朋友圈实时通知、在线协同编辑等)。主流浏览器以及一些常见服务端通信框架(Tomcat、netty、undertow、webLogic等)都对WebSocket进行了技术支持。

版本

2013年以前还没出JSR356标准,Tomcat就对Websocket做了支持,自定义API,再后来有了JSR356,Tomcat立马紧跟潮流,废弃自定义的API,实现JSR356那一套,这就使得在Tomcat7.0.47之后的版本和之前的版本实现方式并不一样,接入方式也改变了。

JSR365是java制定的websocket编程规范,属于Java EE 7的一部分,所以要实现websocket内存马并不需要任何第三方依赖

服务端实现方式

注解方式

@ServerEndpoint(value = "/ws/{userId}", encoders = {MessageEncoder.class}, decoders = {MessageDecoder.class}, configurator = MyServerConfigurator.class)

Tomcat在启动时会默认通过 WsSci 内的 ServletContainerInitializer 初始化 Listener 和 servlet。然后再扫描 classpath下带有 @ServerEndpoint注解的类进行 addEndpoint加入websocket服务

所以即使 Tomcat 没有扫描到 @ServerEndpoint注解的类,也会进行Listener和 servlet注册,这就是为什么所有Tomcat启动都能在memshell scanner内看到WsFilter

继承抽象类Endpoint方式

继承抽象类 Endpoint方式比加注解 @ServerEndpoint方式更麻烦,主要是需要自己实现 MessageHandler和 ServerApplicationConfig@ServerEndpoint的话都是使用默认的,原理上差不多,只是注解更自动化,更简洁

可以用代码更方便的控制 ServerEndpointConfig 内的属性

ServerEndpointConfig serverEndpointConfig = ServerEndpointConfig.Builder.create(WebSocketServerEndpoint3.class, "/ws/{userId}").decoders(decoderList).encoders(encoderList).configurator(new MyServerConfigurator()).build();

websocket内存马实现方法

之前提到过 Tomcat 在启动时会默认通过 WsSci 内的 ServletContainerInitializer 初始化 Listener 和 servlet。然后再扫描 classpath下带有 @ServerEndpoint注解的类进行 addEndpoint加入websocket服务

那如果在服务启动后我们再 addEndpoint 加入websocket服务行不行呢?答案是肯定的,而且非常简单只需要三步。创建一个ServerEndpointConfig,获取ws ServerContainer,加入 ServerEndpointConfig,即可

ServerEndpointConfig config = ServerEndpointConfig.Builder.create(EndpointInject.class, "/ws").build();
ServerContainer container = (ServerContainer) req.getServletContext().getAttribute(ServerContainer.class.getName());
container.addEndpoint(config);

效果

首先利用i.jsp注入一个websocket服务,路径为/x,注入后利用ws连接即可执行命令

且通过memshell scanner查询不到任何异常(因为根本就没注册新的 Listener、servlet 或者 Filter)

代理

WebSocket是一种全双工通信协议,它可以用来做代理,且速度和普通的TCP代理一样快,这也是我研究websocket内存马的原因。

例如有一台不出网主机,有反序列化漏洞。

以前在这种场景下,之前可能会考虑上reGeorg或者利用端口复用来搭建代理。

现在可以利用反序列化漏洞直接注入websocket代理内存马,然后直接连上用上全双工通信协议的代理。

注入完内存马以后,使用 Gost:https://github.com/go-gost/gost 连接代理

./gost -L "socks5://:1080" -F "ws://127.0.0.1:8080?path=/proxy"

然后连接本地1080端口socks5即可使用代理

完整代码:https://github.com/veo/wsMemShell

websocket
本作品采用《CC 协议》,转载必须注明作者和本文链接
WebSocket 测试入门篇
2023-02-08 15:56:52
这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而 HTTP 请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
浅析websocket劫持
2022-07-15 15:43:18
WebSocket劫持漏洞导读WebSocket协议技术WebSocket是HTML5推出的新协议,是基于TCP的应用层通信协议,它与http协议内容本身没有关系。为了建立连接,浏览器和服务器通过HTTP执行WebSocket握手。此时,网络连接保持打开状态,并且可以用于向任一方向发送WebSocket消息。
最近,看到网上有安全研究人员发布了一篇文章,描述了一款在?为此,笔者对该内存马的原理进行了分析,并在此提出了一种检测该内存马的思路,可以帮助安全人员检测出此种类型内存马,从而降低业务系统安全隐患。笔者写了一个简单的 jsp 检测脚本,访问该 jsp 就能打印出所有的 ws 服务。
一种全新的内存马
2022-12-13 10:56:20
前言WebSocket是一种全双工通信协议,即客户端可以向服务端发送请求,服务端也可以主动向客户端推送数据。这样的特点,使得它在一些实时性要求比较高的场景效果斐然。主流浏览器以及一些常见服务端通信框架都对WebSocket进行了技术支持。版本2013年以前还没出JSR356标准,Tomcat就对Websocket做了支持,自定义API,再后来有了JSR356,Tomcat立马紧跟潮流,废弃自定义的API,实现JSR356那一套,这就使得在Tomcat7.0.47之后的版本和之前的版本实现方式并不一样,接入方式也改变了。
浅析JWT安全问题
2022-08-08 15:44:18
观察确定为JWT,将payload处字符base64解码得??把sub的wiener修改为administrator,重新传参??成功越权,然后就是删除用户即可?然后前往jwt.io生成我们需要的的jwt,把sub和secret进行修改??重新传包,成功?
给木马带双眼睛
2023-04-18 09:56:25
近月,内存马的技术也产生新的变化,如利用websocket进行通信,Executor内存马进行socket通信。本文介绍利用Poller内存马实现全流量监控,这样,攻击方可以实时监控经过系统的每一个请求,或者增加了钓鱼等信息利用的便利。这也就是说注入Poller的内存马一定是不能出任何bug的,一旦出了,整个服务直接崩溃。反向,Executor是一个任务类,创建后就执行一个线程任务,如果这次业务异常,最多这次的请求无法正常执行罢了。
近期,观成科技安全研究团队在现网中检测到了利用Gost工具实现加密隧道的攻击行为。
Web 前端与后台的通信短轮询:通过不断发送 http 请求达到即时通信的目的长轮询:访问无资源并不会立刻返回,保持较长时间的通讯,直到获得数据或超时返回。
Spring Framework、5.0.5 之前的 5.0.x 版本和 4.3.16 之前的 4.3.x 版本以及不支持的旧版本允许应用程序通过spring-messaging模块通过简单的内存 STOMP 代理通过 WebSocket 端点公开 STOMP 。恶意用户(或攻击者)可以向代理发送可能导致远程代码执行攻击的消息。
VSole
网络安全专家