一种全新的基于WebSocket的内存马
2022-7-11 10:57:0 Author: Z2O安全攻防(查看原文) 阅读量:28 收藏

免责声明

本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。

只供对已授权的目标使用测试,对未授权目标的测试作者不承担责任,均由使用本人自行承担。

文章正文

1.前言

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

2.版本

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

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

3.服务端实现方式

(1)注解方式

 @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

(2)继承抽象类Endpoint方式

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

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

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

3.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);

4.效果

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

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

5.代理

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

文章来源:https://veo.pub/2022/memshell/

技术交流

交流群

关注公众号回复“加群”,添加Z2OBot 小K自动拉你加入Z2O安全攻防交流群分享更多好东西。

知识星球

星球不定时更新最新漏洞复现,手把手教你,同时不定时更新POC、内外网渗透测试骚操作。涉及方向包括Web渗透、免杀绕过、内网攻防、代码审计、应急响应、云安全等

关注我们

关注福利:

回复“app" 获取  app渗透和app抓包教程

回复“渗透字典" 获取 针对一些字典重新划分处理,收集了几个密码管理字典生成器用来扩展更多字典的仓库。

回复“书籍" 获取 网络安全相关经典书籍电子版pdf

往期文章:

CVE-2022-30190 Follina Office RCE分析【附自定义word模板POC】

邮箱附件钓鱼常用技法

入侵痕迹清理

一篇文章带你学会容器逃逸
spring cloud function spel表达式注入RCE复现
利用burp精准定位攻击者
从此 Typora 代码块有了颜色
不会写免杀也能轻松过defender上线CS

文章来源: http://mp.weixin.qq.com/s?__biz=Mzg2ODYxMzY3OQ==&mid=2247488190&idx=1&sn=12d3772432cd86960232a07d67abc8d1&chksm=cea8f9fef9df70e80a4829fc963f49ae68a1118c344d402d27533b1401b61575df909730cc49#rd
如有侵权请联系:admin#unsafe.sh