wexiaojiu
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
给Web中间件赋能,利用底层TCP会话,传输非HTTP协议数据。
0x00 前言
该文章内容仅作为技术分享,相关案例仅为理论证明提供支撑,仅供合法的渗透测试以及爱好者参考学习,请各位遵守《中华人民共和国网络安全法》以及相应地方的法律,否则自行承担相关责任!
0x01 背景
突发奇想!
0x02 最终成果
为了更好说明该技术特征,通过wireshark抓包观察数据交互特征。这里选择了冰蝎和哥斯拉作为对比参照。
特别说明:并没有表示冰蝎和哥斯拉不好,本文只是个通信方式对比。
冰蝎抓包结果:
哥斯拉抓包结果:
通道维持技术抓包结果:
无论是冰蝎或者哥斯拉,每个命令的执行操作都需要通过HTTP请求实现,而通道维持技术执行命令过程中无HTTP请求。当然通道维持技术并不是不需要HTTP请求,因为最初的通道建立是通过HTTP请求实现的,后续的通信则可以自定义。
实际的TCP流如下图,完整的HTTP Request发送到服务器后,后续就脱离HTTP协议传输明文的tcp data,通过这样的方式接收whoami命令并响应结果,最后end控制服务端完成HTTP响应。(HTTP Request->Diy->HTTP Response)
0x03 技术原理
1、如下图所示常用的Web中间件可以大致分为下列三层业务结构,分别是:
a、网络层(非TCP/IP五层模型的网络层)--主要实现TCP连接和通信,一般通常采用socket来实现;
b、协议层--实现协议的解析和封装,Web中间件主要是实现HTTP协议的解析和封装;
c、处理层--处理协议层提供的数据并生成响应数据,具体实现形式丰富;
2、通常和Web中间件通信都会遵守HTTP协议,来保障对页面的访问和用户交互。冰蝎、哥斯拉也是采用这样的方式实现,最终都需要通过协议层和处理层。但是如果可以控制网络层,那么就可以绕过协议层和处理层。简单来看,只要控制了网络层,便可以操纵Web中间件变成FTP服务器,传输FTP协议通信,更有甚者,可以传输非标准协议数据。
3、基于上述思路以Tomcat为例进行可行性探索。以Tomcat环境上运行的JSP脚本为出发点,验证上述思路的可行性,是否能通过JSP脚本控制Web中间件网络层。经过一小段时间的探索,寻找到了下图所示调用链:
4、通过上图所示调用链的制定,可以顺利获取当前TCP会话的SocketWrapperBase实例,
只需要调用SocketWrapperBase的read、write方法,就能自由的在当前TCP会话中传输非HTTP协议数据。
5、值得注意,这里只是获取了TCP会话,并未阻断服务器对正常HTTP请求的处理和响应过程,不会影响服务端的正常运行。
0x04 缺陷
该技术需要基于与Web中间件建立TCP会话,如果中间通过了反向代理,例如:Nginx,那么实质上建立的是与反向代理通信的TCP会话。反向代理通常是处理完整的协议内容后再行转发,这就会导致发送内容非标准协议内容就不会抵达真实的服务端。如果是传输完整的协议,那就不需要本文多此一举了。
0x05 Demo
JSP脚本demo
<% if (request instanceof RequestFacade) { Field requestField = RequestFacade.class.getDeclaredField("request"); requestField.setAccessible(true); Connector connector = ((Request) requestField.get(request)).getConnector(); ProtocolHandler handler = connector.getProtocolHandler(); if (handler instanceof Http11NioProtocol) { try { Field endpointFiled = AbstractProtocol.class.getDeclaredField("endpoint"); endpointFiled.setAccessible(true); NioEndpoint endpoint = (NioEndpoint) endpointFiled.get(handler); SocketWrapperBase<NioChannel> socketWrapper = null; for (SocketWrapperBase<NioChannel> temp : endpoint.getConnections()) { if (temp.getRemoteAddr().equals(request.getRemoteAddr()) && temp.getLocalPort() == request.getLocalPort()) { socketWrapper = temp; break; } } if (socketWrapper != null) { //实现通信 } } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } %>
0x06 总结
对上述内容简单总结下:
1、通道维持技术就不是个新技术,只是利用特定的方法截获了当前的TCP会话,并实现协议外的内容传输;
2、依赖客户端到目标端的TCP会话,如果经过反向代理链路自身不完整,无法实现协议外的内容传输;
3、主要是分享了一个传输数据的思路,控制应用的底层来实现自定义的传输不拘束于协议。
0x07 思考
1、个人也无法确认该技术是否早就存在,如有雷同纯属巧合;
2、当下是否具备检测该通信行为的能力,端口是防火墙开放的端口,传输的数据却是解析不了的数据;
3、该技术至少有2个明显的特征:1)肯定是一个长连接;2)标准端口非标准数据;
4、除了tomcat,其他的java中间件应该也可以搞定,不知道php、.net是否也可以利用,除了Web中间件,其他应用是否也有这样的可能;
0x08 转载来源
https://mp.weixin.qq.com/s/0TDaz-tH5w3g6e7D4lx7bA
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)