Web协议层安全之websocket安全分析

admin 2022年6月17日10:59:13安全文章评论5 views7262字阅读24分12秒阅读模式

一、 概 述
WebSocket 是HTML5一种新的网络传输协议,位于 OSI 模型的应用层,可在单个TCP连接上进行全双工通信。

1.1   HTTP 和 WebScoket

段落的首行要缩进,表格居中放置,如表1。字体通一用一种雅黑或宋体,文字字号统一为5号Web 客户端和服务端之间的大多数通信使用HTTP(HTTPS也是在传输层和应用层中间加了一层SSL/TLS协议,在这里没有太大影响,故不作区分)。HTTP协议是请求-响应式的,在 HTTP1.1 开始,TCP连接可被复用。即使网络连接保持打开状态,这也将用于请求和响应的单独事务。
 
WebSocket和HTTP都是应用层协议,并且都基于TCP协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就可以建立持久性的连接,并进行双向数据传输。此外,WebSocket基于二进制帧进行传输。

RFC 6455中规定:
WebSocket通过HTTP端口80和443进行工作,并支持HTTP代理和中介,从而使其与HTTP协议兼容。
TIPS:ws协议默认80端口,wss默认443端口
为了实现兼容性,WebSocket握手使用HTTP Upgrade 头从HTTP协议更改为WebSocket协议。与HTTP协议类似, `wss` 协议建立在一个加密的TLS连接的WebSocket,而 `ws` 协议使用未加密的连接。

1.2   Demo

  • 安装依赖
 npm install ws
  • server.js
 // 导入WebSocket模块:
 const WebSocket = require('ws');
 
 // 引用Server类:
 const WebSocketServer = WebSocket.Server;
 
 // 实例化:
 const ws = new WebSocketServer({
     port: 3000
 });
 
 // connection事件用于处理接入的WebSocket
 ws.on('connection', function (ws) {
  console.log("Connected!!!");
 });
node tt.js 启动服务端
  • client
直接在浏览器的console界面输入,在服务端的终端会打印相关的日志信息。
 var ws = new WebSocket("ws://127.0.0.1:3000");

1.3   握手过程

服务端:
 <html>
  <body>
  <script>var ws = new WebSocket("ws://127.0.0.1:3000");</script>
  Loaded!!
  </body>
 </html>

客户端发起握手请求
 GET / HTTP/1.1
 Host: 127.0.0.1:3000
 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0
 Accept: */*
 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
 Accept-Encoding: gzip, deflate
 Sec-WebSocket-Version: 13
 Origin: http://127.0.0.1
 Sec-WebSocket-Key: 8PbhQOV5ykV3eYf2biw52A==
 Connection: keep-alive, Upgrade
 Sec-Fetch-Dest: websocket
 Sec-Fetch-Mode: websocket
 Sec-Fetch-Site: same-site
 Pragma: no-cache
 Cache-Control: no-cache
 Upgrade: websocket
 
如果服务端接受这个连接,它会返回一个WebSocket回复
 HTTP/1.1 101 Switching Protocols
 Upgrade: websocket
 Connection: Upgrade
 Sec-WebSocket-Accept: dBaGq6Oh1nXvQd+sJRKFK9GnsGI=

之后,这个WebSocket的网络连接会保持开启状态,任意一方都可以直接发送WebSocket信息:
 <html>
   <body>
   <script>
     var ws = new WebSocket("ws://127.0.0.1:3000");
 
     // 连接打开事件
     ws.onopen = function() {
         // 发送数据给服务端
         ws.send(JSON.stringify({"message":"hello"}));
      };
 
     // 监听服务端信息
     ws.onmessage = function(e){
         alert(e.data);
    };
   </script>
  Loaded!!
   </body>
 </html>
 
通过 message 监听消息
 // 导入WebSocket模块:
 const WebSocket = require('ws');
 
 // 引用Server类:
 const WebSocketServer = WebSocket.Server;
 
 // 实例化:
 const ws = new WebSocketServer({
     port: 3000
 });
 
 // connection事件用于处理接入的WebSocket
 ws.on('connection', function (ws) {
  // 处理客户端的消息
  ws.on('message', function (data) {
  console.log(JSON.parse(data));
  });
 
  // 向客户端发送消息
  ws.send("OK");
 
 });

原则上,WebSocket消息可以包含任何内容或数据格式。在实际的应用程序中,通常WebSocket消息都是通过JSON进行发送结构化数据。

关于WebSocket握手时的一些特性:
  • Connection和Upgrade头部用来标识这是一个WebSocket握手消息。
  • Sec-WebSocket-Version请求头明确了一个客户端希望使用的WebSocket协议版本。版本13最常用。
  • Sec-WebSocket-Key请求头包含了一个base64编码的随机值,在每个WebSocket握手请求中,它一定是随机生成的。
  • Sec-WebSocket-Accept响应头的值是客户端发送的握手请求中Sec-WebSocket-key的哈希值,并与协议规范中定义的特定字符串连接。这样做的目的是匹配每一对握手请求,防止由于错误的配置或者缓存代理导致的连接错误。

1.4   握手过程

基于WebSocket全双工、延迟的特性,应用场景比较广泛。
  • 聊天机器人
  • 弹幕
  • 协同编辑
  • 股票报价实施更新
  • 位置更新
  • 直播实况段落的首行要


二、 安 全 分 析

根据上面的分析可知,WebSocket仅仅是Web程序中的一种通信协议,并不会解决Web应用中存在的安全问题。因此,原则上任何Web漏洞都有可能出现在使用WebSocket的应用中。

2.1   Web漏洞

WebSocket中,用户可控的请求数据,都会涉及输入校验问题,用来规范常见的Web漏洞,如XSS、SQL Inject、RCE等。

2.1.1     XSS

靶场环境:https://acb51fa71e7c52cbc04a0bac00b7009c.web-security-academy.net/
题目环境是一个商城,其中有个在线聊天功能,是基于WebSocket
to server
{"message":"<img src=1 onerror='alert(1)'>"}
to client
{"user":"You","content":"<img src=1 onerror='alert(1)'>"}
页面渲染后触发js
Web协议层安全之websocket安全分析
TIPS:新版的Burp 支持WebSocket包重放
 

2.2   WebSocket 安全


2.2.1          认证

WebSocket 协议并没有在握手阶段对客户端的身份进行认证,但服务端可以采用HTTP服务器的客户端身份认证机制,如cookie认证,HTTP 基础认证,TLS 身份认证等。因此,认证实现方面的安全问题与基于HTTP的Web认证并无区别。
  • CVE-2015-0201
      Spring框架的Java SockJS客户端生成可预测的会话ID,攻击者可利用该漏洞向其他会话发送消息
  • CVE-2015-1482
      Ansible Tower未对用户身份进行认证,远程攻击者通过websocket连接获取敏感信息

2.2.1     授权

WebSocket 协议依然没有指定任何授权方式,因此关于权限的相关策略依然得依赖开发者在服务端实现,依然面临着垂直权限提升和水平权限提升的风险。

2.2.1    跨域请求/CSWSH

WebSocket使用基于源的安全模型,在发起WebSocket握手请求时,浏览器会在请求中添加一个名为Origin的HTTP头,Oringin字段表示发起请求的源,以此来防止未经授权的跨站点访问请求。

WebSocket 的客户端不仅仅局限于浏览器,因此 WebSocket 规范没有强制规定握手阶段的 Origin 头是必需的,并且WebSocket不受浏览器同源策略、CORS机制的限制。如果服务端没有针对Origin头部进行验证可能会导致跨站点WebSocket劫持攻击。

CSWSH全称Cross-site WebSocket Hijacking,跨站点WebSocket劫持漏洞。

该漏洞最早在 2013 年被Christian Schneider 发现并公开,Christian 将之命名为跨站点 WebSocket 劫持 (Cross Site WebSocket Hijacking)(CSWSH)。跨站点 WebSocket 劫持危害大,但容易被开发人员忽视。相关案例可以参考: IPython Notebook(CVE-2014-3429), OpenStack Compute(CVE-2015-0259), Zeppelin WebSocket服务器等跨站WebSocket劫持。

攻击过程:
 
Web协议层安全之websocket安全分析
需要注意的是,Origin 和 Sec-WebSocket-Key 都是由浏览器自动生成的,浏览器再次发起请求访问目标服务器会自动带上Cookie 等身份认证参数。

漏洞利用的关键点是,服务端没有对Origin头部进行校验,才能成功握手并切换到 WebSocket 协议,恶意网页就可以成功绕过身份认证连接到 WebSocket 服务器,进而窃取到服务器端发来的信息,或者发送伪造信息到服务器端篡改服务器端数据。

检测
由于跨站点WebSocket劫持攻击本质上是WebSocket握手上的CSRF漏洞,因此,首先需要确认在WebSocket握手过程中,是否进行了CSRF防护,确定是否仅仅依赖HTTP cookie进行权限鉴定。

 HTTP/1.1 101 Switching Protocols
 Upgrade: websocket
 Connection: Upgrade
 Cookie: session=KOsEJNuflw4Rxxxxxxxxxxxxxx
 Sec-WebSocket-Accept: dBaGq6Oh1nXvQd+sJRKFK9GnsGI=

TIPS:Sec-WebSocket-Key头包含一个随机值,以防止缓存代理的错误,而不是用于身份验证或会话处理的目的。

在确定握手请求存在CSRF风险的情况下,寻找使用WebSocket进行敏感数据检索的功能点。

过程:
  1. 重放确认是否存在CSRF
  2. 修改Origin头部,判断是否存在校验
对比CSRF
与传统跨站请求伪造(CSRF)攻击相比,CSRF 主要是通过恶意网页悄悄发起数据修改请求,而跨站 WebSocket 伪造攻击不仅可以修改服务器数据,还可以控制整个双向通信通道。也正是因为这个原因,Christian 将这个漏洞命名为劫持(Hijacking),而不是请求伪造(Request Forgery)。

防御
  • 检查客户端请求中的Origin信息是否跨域
  • 防止Origin头部伪造,还可以借鉴CSRF的防御机制,如增加Token验证

2.2.2         拒绝服务攻击/DOS

WebSocket设计为面向连接的协议,如果不限制连接数,可能会导致DoS风险。
F5 BIG-IP远程拒绝服务漏洞(CVE-2016-9253)
  • 客户端拒绝服务
WebSocket 连接限制不同于HTTP连接限制,WebSocket有一个更高的连接限制,不同的浏览器的最大连接数也存在差异。如:火狐浏览器默认最大连接数为200。
通过发送恶意内容,占用所有Websocket,导致浏览器资源耗尽,引起拒绝服务。
  • 服务端拒绝服务
    • 发起大量连接
WebSocket建立的是持久连接,只有客户端或服务端其中一方发起关闭连接的请求,连接才会关闭。攻击者可以通过发起请求并建立大量的连接,导致服务器资源耗尽,引发拒绝服务攻击。
防御:服务端可以进行单一IP的最大连接数进行防御
  • 大数据帧占用
攻击者可以发送一个庞大的数据帧,占用服务端的内存,引发拒绝服务攻击,
防御:限制帧的大小
demo
  • js
 var WebSocketServer = require('ws').Server,
 wss = new WebSocketServer({ port: 3000 });
 wss.on('connection', function (ws) {
     console.log('[*]Client connected!');
     ws.on('message', function (message) {
         console.log(message.toString('utf8'));
    });
 });
  • 正常客户端
 <html>
   <body>
   <script>
     var ws = new WebSocket("ws://127.0.0.1:3000");
 
     // 连接打开事件
     ws.onopen = function() {
         // 发送数据给服务端
         ws.send("Hello");
      };
 
     // 监听服务端信息
     ws.onmessage = function(e){
         alert(e.data);
    };
   </script>
  Loaded!!
   </body>
 </html>
 
  • exp
 python -m pip install ws4py from ws4py.client.threadedclient import WebSocketClient
 class WS_Client(WebSocketClient):
 
     # 需要重写以下三个方法
     def opened(self):
         reqData = "Hello"
         self.send(reqData)

     def closed(self, code, reason=None):
         print("[-] Closed down:", code, reason)
  
     def received_message(self, resp):
         resp = json.loads(str(resp))
         print(resp)
 if __name__ == '__main__':
     while True:
         ws = WS_Client("ws://127.0.0.1:3000")
         ws.connect()

2.2.3              中间人攻击

WebSocket使用HTTP或HTTPS协议进行握手请求,在使用HTTP协议的情况下,若存在中间人可以嗅探HTTP流量,那么中间人可以获取并篡改WebSocket握手请求,通过伪造客户端信息与服务器建立WebSocket连接。短文章可以不引用目录。


三、 总 结

WebSocket 是HTML5中一个及时的全双工通讯协议,在性能上有着明显的优势,但他并不能解决安全问题,同时也需要开发者考虑其安全威胁面。


四、 参 考

https://christian-schneider.net/CrossSiteWebSocketHijacking.html
https://www.liaoxuefeng.com/wiki/1022910821149312/1103327377678688
https://segmentfault.com/q/1010000020661067
https://www.mi1k7ea.com/2019/10/04/CSWSH%E6%BC%8F%E6%B4%9E%E6%80%BB%E7%BB%93/#0x02-CSWSH%E6%BC%8F%E6%B4%9E
https://security.tencent.com/index.php/blog/msg/119
https://www.mi1k7ea.com/2021/01/30/%E6%B5%85%E6%9E%90WebSocket%E5%AE%89%E5%85%A8/
https://www.freebuf.com/articles/web/252298.html
https://wiki.wgpsec.org/knowledge/web/websocket-sec.html
https://www.mi1k7ea.com/2021/01/30/%E6%B5%85%E6%9E%90WebSocket%E5%AE%89%E5%85%A8/

Web协议层安全之websocket安全分析


原文始发于微信公众号(山石网科安全技术研究院):Web协议层安全之websocket安全分析

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年6月17日10:59:13
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  Web协议层安全之websocket安全分析 http://cn-sec.com/archives/1124278.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: