Websockets测试¶
WebSockets 在现代网页应用中被广泛使用。它们通过 HTTP 协议进行通信,提供长寿命的连接,并且支持双向异步通信。
WebSockets 被广泛应用于各种场景,包括执行用户操作以及传输敏感信息。实际上,任何与常规 HTTP 通信相关的网络安全漏洞,在 WebSockets 通信中同样可能出现。
什么是Websockets¶
HTTP和Websockets有什么区别¶
大多数网页浏览器与网站之间的通信都通过 HTTP 进行。在 HTTP 协议中,客户端发送请求,服务器则返回响应。通常情况下,响应会立即出现,从而完成整个通信过程。即使网络连接保持开启状态,这也只会被用于后续的请求与响应的处理中。
一些现代网站使用 WebSockets 技术。WebSocket 连接是通过 HTTP 协议建立的,通常属于持久性连接。消息可以双向发送,且不具有事务性特征。这种连接通常会保持开放状态,直到客户端或服务器准备好发送消息为止。
在需要低延迟或服务器主动发送消息的情况下,WebSockets 非常有用,比如实时传输金融数据这样的场景。
Websockets如何建立链接¶
WebSocket 连接通常是通过客户端 JavaScript 来创建的,如下所示:
Note
wss 协议通过加密的 TLS 连接建立 WebSocket 连接,而 ws 协议则使用非加密的连接方式。
为了建立连接,浏览器和服务器通过 HTTP 协议进行 WebSocket 握手。浏览器会发出如下所示的 WebSocket 握手请求:
GET /chat HTTP/1.1
Host: normal-website.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: wDqumtseNBJdhkihL6PW7w==
Connection: keep-alive, Upgrade
Cookie: session=KOsEJNuflw4Rd9BDNrVmvwBF9rEijeE2
Upgrade: websocket
如果服务器接受了连接,它会返回如下的 WebSocket 握手响应:
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: 0FFP+2nmNIf/h+4BP36k9uzrYGk=
此时,网络连接仍然处于开放状态,可以用于发送双向的 WebSocket 消息。
Note
WebSocket 握手消息有几个特点值得注意:
- 请求和响应中的
Connection和Upgrade头部表明这是一次 WebSocket 握手过程。 Sec-WebSocket-Version请求头中指定了客户端所使用的 WebSocket 协议版本。通常这个版本为13。Sec-WebSocket-Key请求头中包含了一个 Base64 编码的随机值,这个随机值应该在每次握手请求中生成。Sec-WebSocket-Accept响应头中包含着Sec-WebSocket-Key请求头中提交的值的哈希值,该哈希值与协议规范中定义的特定字符串进行连接。这样做是为了防止由于服务器配置错误或代理服务器缓存导致的误导性响应。
Websockets消息长什么样¶
一旦建立了 WebSocket 连接,客户端或服务器就可以双向异步地发送消息。
可以通过浏览器使用客户端 JavaScript 发送一个简单的消息,如下所示:
原则上,WebSocket 消息可以包含任何类型的内容或数据格式。在现代应用中,通常使用 JSON 格式来在 WebSocket 消息中传递结构化数据。
例如,一个使用 WebSockets 的聊天机器人应用程序可能会发送如下这样的消息:
{"user":"Hal Pline","content":"I wanted to be a Playstation growing up, not a device to answer your inane questions"}
操控Websockets流量¶
拦截并修改¶
你可以使用 Burp Proxy 来拦截和修改 WebSocket 消息,具体操作如下:
- 打开 Burp 的浏览器界面。
- 找到使用 WebSockets 的应用程序功能。你可以通过查看应用程序来确认是否使用了 WebSockets,然后在 Burp Proxy 中的 WebSockets 历史记录选项卡中查找相关的记录。
- 在 Burp Proxy 的“拦截”选项卡中,确保已经启用了拦截功能。
- 当来自浏览器或服务器的 WebSocket 消息被发送时,它会显示在“拦截”标签页中,供您查看或修改。点击“转发”按钮即可将消息转发出去。
Note
你可以在 Burp 代理中配置是否拦截客户端到服务器的消息,或者服务器到客户端之间的消息。这些设置可以在“设置”对话框中的“WebSocket 拦截规则”选项中进行配置。
重放和生成新的¶
除了能够实时拦截和修改 WebSocket 消息之外,你还可以重新发送单个消息以及生成新的消息。你可以使用 Burp Repeater 来实现这一功能:
- 在 Burp Proxy 中,选择 WebSockets 历史记录中的某条消息,或者从“拦截”选项卡中选择该消息,然后从上下文菜单中选择“发送到转发器”。
- 在 Burp Repeater 中,现在可以编辑被选中消息,并反复发送该消息。
- 你可以输入一条新的消息,然后将其发送到任何方向:无论是客户端还是服务器。
- 在 Burp Repeater 的“历史记录”面板中,你可以查看通过 WebSocket 连接传输的所有消息的历史记录。这些记录包括你在 Burp Repeater 中生成的消息,以及通过同一连接由浏览器或服务器生成的消息。
- 如果您想要编辑并重新发送历史面板中的任何消息,可以选择该消息,然后从上下文菜单中选择“编辑并重新发送”选项。
控制Websockets连接¶
除了可以操作 WebSocket 消息之外,有时还需要对建立连接的 WebSocket 握手过程进行干预。
在多种情况下,可能需要操控 WebSocket 的连接过程:
- 它能够帮助你触及更广泛的攻击范围。
- 有些攻击可能会导致连接中断,因此你需要建立一个新的连接。
- 在最初的握手请求中,令牌或其他数据可能已经过时,需要进行更新。
你可以通过使用 Burp Repeater 来操控 WebSocket 的连接过程:
- 如已所述,将 WebSocket 消息发送到 Burp Repeater。
- 在 Burp Repeater 中,点击 WebSocket URL 旁边的铅笔图标。这将打开一个向导,允许你连接到一个已连接的 WebSocket 实例、克隆一个已连接的 WebSocket,或者重新连接到一个已断开连接的 WebSocket。
- 如果您选择克隆一个已连接的 WebSocket,或者重新连接到一个已断开连接的 WebSocket,那么向导会显示完整的 WebSocket 握手过程细节。您可以在执行握手操作之前根据需要进行相应的编辑。
- 当您点击“连接”按钮时,BURP 会尝试执行所配置的握手过程,并展示结果。如果成功建立了新的 WebSocket 连接,那么就可以使用这个连接在 BURP 中继器中发送新的消息了。
Websockets存在的漏洞¶
原则上,实际上任何与 WebSockets 相关的网络安全漏洞都有可能出现。
- 用户提供的输入被传输到服务器后,可能会以不安全的方式被处理,从而导致诸如 SQL 注入或 XML 外部实体注入等安全漏洞的出现。
- 一些通过 WebSockets 传播的隐藏漏洞,可能只能通过外部检测技术来发现。
- 如果攻击者控制的数据通过 WebSockets 传输到其他应用程序用户手中,那么可能会导致 XSS 攻击或其他客户端方面的漏洞。
大多数与 WebSockets 相关的输入相关漏洞,都是通过篡改 WebSocket 消息的内容来发现和利用的。
例如,假设某个聊天应用程序使用 WebSockets 在浏览器和服务器之间传递聊天消息。当用户输入一条聊天消息时,就会向服务器发送如下所示的 WebSocket 消息:
消息的内容再次通过 WebSockets 被传输到另一个聊天用户那里,并在该用户的浏览器中呈现出来。
在这种情况下,如果不存在其他输入处理或防御措施,攻击者可以通过发送以下 WebSocket 消息来实施 XSS 攻击:
一些 WebSocket 漏洞只有通过操控 WebSocket 握手过程才能被发现并利用。这些漏洞往往源于设计上的缺陷,例如:
- 人们过于依赖 HTTP 头部来做出安全决策,比如
X-Forwarded-For这样的头部。 - 在会话处理机制中存在缺陷,因为 WebSocket 消息的处理所依赖的会话上下文,通常是由握手消息的会话上下文来决定的。
- 应用程序使用的自定义 HTTP 头信息引入了攻击面。
Note
一些 WebSocket 的安全漏洞出现在攻击者能够从一个自己控制的网站发起跨域 WebSocket 连接时。这种攻击被称为跨站 WebSocket 劫持攻击,它利用了 WebSocket 握手过程中的跨站请求伪造漏洞。这种攻击往往会产生严重的后果,使得攻击者能够代表受害用户执行特权操作,或者获取受害者有权访问的敏感数据。
如何保护Websockets连接的安全¶
为了降低与 WebSockets 相关的安全漏洞风险,请遵循以下建议:
- 使用
wss://协议(基于 TLS 的 WebSockets)。 - 请硬编码 WebSockets 端点的 URL,切勿在该 URL 中包含可由用户随意修改的数据。
- 需要保护 WebSocket 握手消息免受 CSRF 攻击,以避免跨站 WebSocket 劫取漏洞的出现。
- 对于通过 WebSocket 传输的数据,在双向通信中都应将其视为不可信赖的数据。在服务器和客户端两端都要小心处理这些数据,以避免出现诸如 SQL 注入和跨站脚本攻击等基于输入漏洞的安全风险。