WebSocket Turbo Intruder:挖掘WebSocket安全漏洞的利器

本文介绍了WebSocket Turbo Intruder工具,这是一个Burp Suite扩展,专门用于WebSocket协议的安全测试。文章详细讲解了工具的核心功能、安装使用方法,并展示了如何利用它发现服务器端原型污染、竞争条件等漏洞,同时提供了自动化测试和高级调试技巧。

WebSocket Turbo Intruder:挖掘WebSocket安全漏洞的利器

许多测试人员和工具在协议升级到WebSocket时就会放弃,或仅进行浅层分析。这是一个巨大的盲点,导致许多漏洞未被发现,如破碎的访问控制、竞争条件和SQL注入。在本文中,我们将介绍新版本的WebSocket Turbo Intruder,这是一个Burp Suite扩展,将Turbo Intruder的快速攻击引擎引入WebSocket测试。我们还将讨论为什么自动扫描WebSocket应用很困难,以及这个工具如何帮助解决这些问题。

大纲

  • 引言
  • 主要功能
  • 入门指南
  • 基本使用
  • 过滤无关内容
  • 自动化测试
  • 漏洞利用
    • 服务器端原型污染
    • 竞争条件
    • Ping of Death
  • 高级功能
    • 命令行界面
    • 调试模式
  • 参考文献

引言

WebSocket Turbo Intruder是一个Burp Suite扩展,用于使用自定义Python代码对WebSocket消息进行模糊测试。它扩展了Burp Suite引擎,使其能够利用WebSocket协议特定的漏洞。

主要功能

  • 高速 - 支持每秒数千条消息
  • HTTP适配器 - 通过与现有HTTP扫描器集成实现自动化测试
  • 智能过滤 - 隐藏无关响应,让您专注于有趣的结果

虽然WebSocket Turbo Intruder包含一个用于速度的自定义引擎,但它不如Burp的内置引擎经过实战测试。如果您看到错误或连接问题,请尝试切换回默认引擎。此外,此工具专为针对单个目标进行高容量测试而设计 - 由于WebSocket连接必须保持打开状态,测试大范围目标很棘手且不受良好支持。

入门指南

您可以直接从BApp商店安装WebSocket Turbo Intruder,这是最简单的入门方式。转到Extensions → BApp Store → WebSocket Turbo Intruder并单击Install。如果您喜欢自己构建或想探索源代码,该项目可在GitHub上获得。安装后,当您在Burp Suite中右键单击任何消息时,扩展将显示为新菜单项。

基本使用

该扩展附带两个内置工具:Turbo Intruder和HTTP Middleware。当您想向单个目标发送数千条WebSocket消息并查找有趣行为时,第一个工具最合适。第二个工具用于自动化扫描,我们稍后会回到这一点。

让我们从一个基本的Python脚本示例开始。我们将使用它来测试PortSwigger Academy实验室:操纵WebSocket消息以利用漏洞。

当单击Attack按钮时,此脚本发送10个不同的数值作为消息JSON值的一部分。结果表(如屏幕截图中所示)将包含扩展处理的所有请求(传出消息)和响应(传入消息)。

过滤无关内容

与HTTP不同,WebSocket协议可以为一条传出消息发送多条传入消息。这使得测试变得更加困难,因为表格很快充满了噪音。在我们的案例中,单个"请求"触发了三个不同的"响应"。为了处理这个问题,扩展包括强大的过滤器。这些让您可以隐藏不相关的流量,并将请求锁定到您关心的响应。以下是一个装饰器示例,仅保留来自用户Hal Pline的消息并过滤掉其他所有内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def queue_websockets(upgrade_request, message):
    connection = websocket_connection.create(upgrade_request)
    for i in range(10):
        connection.queue(message, str(i))
        
def handle_outgoing_message(websocket_message):
    results_table.add(websocket_message)

@MatchRegex(r'{"user":"Hal Pline"')
def handle_incoming_message(websocket_message):
    results_table.add(websocket_message)

自动化测试

如果您不喜欢手动查看结果表,可以使用WebSocket Turbo Intruder HTTP Middleware将WebSocket连接包装在HTTP请求中。从Proxy History中选择任何WebSocket消息,然后右键单击并选择Extensions → WebSocket Turbo Intruder → Send to WebSocket HTTP Middleware。这使您可以使用过滤器仅捕获您关心的流量,同时通过本地HTTP端点与服务器交互。

例如,这里我们使用包含的ServerExample.py脚本创建WebSocket连接,并过滤传入消息仅显示从PortSwigger Academy实验室回显的消息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def create_connection(upgrade_request):
    connection = websocket_connection.create(upgrade_request)
    return connection

def handle_outgoing_message(websocket_message):
    results_table.add(websocket_message)

@MatchRegex(r'{"user":"You"')
def handle_incoming_message(websocket_message):
    results_table.add(websocket_message)

从现在开始,我们可以向localhost发送HTTP POST请求,请求体被视为WebSocket消息。这允许您使用像Burp Suite Pro这样的自动化扫描器扫描任何WebSocket。

1
2
3
4
5
POST /proxy?url=https%3A%2F%2F0a7c00a903d17c5a801d35d8008a007a.web-security-academy.net%2Fchat HTTP/1.1
Host: 127.0.0.1:9000
Content-Length: 16

{"message":"hi"}

您可以自定义此代码以匹配目标应用程序的逻辑。此设置非常适合查找服务器端漏洞,如SQL注入、身份验证绕过或命令注入。

漏洞利用

除了常见的应用程序错误外,WebSocket还带来了自己独特的攻击面。接下来我们将看看其中的一些。

WebSocket服务器端原型污染

Socket.IO是一个流行的JavaScript框架,带有自己的WebSocket实现。这使得测试更加复杂 - 但使用WebSocket Turbo Intruder,您可以绕过这些限制。

确认服务器使用Socket.IO的最简单方法是检查强制查询参数EIO,它指定协议版本。如果它等于4,服务器会发送ping数据包。我们可以使用内置的Ping和Pong装饰器自动化此过程。之后,脚本发送初始消息"40"开始对话,其余逻辑照常工作。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import burp.api.montoya.http.message.params.HttpParameter as HttpParameter;

def queue_websockets(upgrade_request, message):
    connection = websocket_connection.create(
        upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4")))
    connection.queue('40')
    connection.queue('42["message","hello"]')

@Pong("3")
def handle_outgoing_message(websocket_message):
    results_table.add(websocket_message)

@PingPong("2", "3")
def handle_incoming_message(websocket_message):
    results_table.add(websocket_message)

Socket.IO协议的HTTP适配器脚本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import burp.api.montoya.http.message.params.HttpParameter as HttpParameter;

def create_connection(upgrade_request):
    connection = websocket_connection.create(
        upgrade_request.withUpdatedParameters(HttpParameter.urlParameter("EIO", "4")))
    connection.queue('40')
    connection.decIn()
    return connection

@Pong("3")
def handle_outgoing_message(websocket_message):
    results_table.add(websocket_message)

@PingPong("2", "3")
def handle_incoming_message(websocket_message):
    results_table.add(websocket_message)

有趣的是,Socket.IO中的一些协议怪癖使其成为服务器端原型污染的良好候选者。如Gareth的早期研究"服务器端原型污染:无需DoS的黑盒检测"所示,可以滥用Express服务器功能来检测成功的污染。使用相同的技术在这里,我们可以通过使用以下内容污染initialPacket属性来诱使Socket.IO返回新的问候消息:{"__proto__":{"initialPacket":"Polluted"}}

WebSocket竞争条件

默认的Intruder脚本通过单个连接以块形式发送消息。这对性能很好,但在测试竞争条件漏洞时没有用,因为时间和并发性很重要。

为了帮助解决这个问题,WebSocket Turbo Intruder包含一个特殊的引擎类型称为THREADED。此引擎启动多个工作线程,每个线程都有自己的WebSocket连接,并并行发送消息。这使得触发经典竞争条件成为可能,如逻辑绕过、令牌重用或状态不同步错误。

如果您不熟悉Python线程,不用担心 - 包含的RaceConditionExample.py脚本只需要小的更改即可适应您的目标。最重要的设置在config()方法中定义:控制打开多少同时连接的线程数。

这种线程模型让您更好地控制并发性,并让您尝试对单连接模糊测试不可见的时间敏感问题。

WebSocket Ping of Death

在测试竞争条件时,我在一个Java WebSocket实现中意外发现了一个拒绝服务漏洞。

根据RFC,WebSocket帧以指定操作码和有效负载长度的标头开始。但是如果长度与实际有效负载不匹配 - 或者有效负载根本没有发送会发生什么?

使用TURBO引擎,我们可以发送任何类型的WebSocket帧,包括格式错误的帧。这允许我们手动调整标头中的有效负载长度,而无需发送千兆字节的数据。Java WebSocket实现存在以下问题。它读取消息标头并使用标头有效负载长度字段中的用户指定值在服务器上分配一个巨大的缓冲区,如果该值是Integer Max Value,则导致内存不足崩溃。之后服务器不再响应任何连接尝试。您可以在扩展附带的PingOfDeathExample.py中找到完整的源代码。

高级功能

命令行界面

WebSocket Turbo Intruder还包括一个独立的CLI,非常适合自动化、脚本编写或在Burp Suite外运行攻击。以下是一个基本用法示例:

1
java -jar WebSocketFuzzer-2.0.0.jar <scriptFile> <requestFile> <endpoint> <baseInput>

命令行支持相当基础。但对于在单个目标上运行长时间攻击非常有用,尤其是在后台作业中。

调试模式

WebSocket Turbo Intruder包含一个内置的WS Logger功能,记录多达1,000条WebSocket消息。这在调试使用HTTP Middleware的脚本时特别有用,其中正确匹配传出和传入消息是关键。

在WebSocket Turbo Intruder → Logger On上启用记录器后,您可以跟踪消息内容及其内部ID。这些ID用于配对请求和响应 - 因此如果某些东西中断或消息不匹配,您可以检查日志以找出问题所在。

如果需要,您还可以通过使用Connection接口中的dec和inc方法来微调消息ID的处理方式。这使您可以完全控制消息的分配和分组方式。

参考文献

在开发WebSocket Turbo Intruder时,我从一些优秀的工作中汲取了灵感,包括@albinowax的"Turbo Intruder:拥抱十亿请求攻击"、@garethheyes的"服务器端原型污染:无需DoS的黑盒检测"和@vah_13的"WebSocket中的竞争条件"。

注意事项

一个快速的注意事项 - WebSocket Turbo Intruder功能强大。它可以每秒发送数千条消息并并行打开许多连接。如果您不小心,可能会使服务器过载或触发拒绝服务条件。始终在允许自动化扫描的目标上使用它,并尽量不要在这样做时使互联网瘫痪。

报告错误和功能请求

WebSocket Turbo Intruder还支持自动Ping/Pong消息和使用isInteresting()方法的内置过滤等功能。您可以在Github存储库中了解这些和其他高级选项的更多信息。如果您发现错误或有功能请求,请随时打开新问题。

演示录像将很快在Black Hat Arsenal频道上提供。祝您好运,玩得开心。

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