目录导航
Turbo Intruder介绍
官网描述为:Turbo Intruder:迎接十亿请求攻击
自动化的 Web 应用程序攻击最终受到它们可以发送的 HTTP 请求数量的限制。不知道有多少黑客已经脱轨了,因为您没有完全设法暴力破解密码、错过竞争条件或未能找到关键文件夹。
在本演示文稿中,我介绍、演示和分发 Turbo Intruder – 一个研究级开源Burp Suite 扩展,从头开始构建并考虑到速度。我还讨论了潜在的 HTTP 滥用使其运行如此之快,因此您可以在碰巧编写的任何工具中获得相似的速度。
Bugcrowd 的 LevelUp #03 在线会议的直播录音视频:

yunzhongzhuan.com/#sharefile=QvmnOOaF_8879



Turbo Intruder使用方法
如果您不喜欢视频,这里简要概述了何时以及如何使用它。
Turbo Intruder 是一个 Burp Suite 扩展,用于发送大量 HTTP 请求并分析结果。它旨在通过处理需要非凡速度、持续时间或复杂性的攻击来补充Burp Intruder的不足之处。
以下功能使其与众不同:
- 快速– Turbo Intruder 使用从头开始手工编码的 HTTP 堆栈,并考虑到速度。因此,在许多目标上,它甚至可以严重超过流行的异步 Go 脚本。
- 可扩展– Turbo Intruder 可以实现平坦的内存使用,从而实现可靠的多日攻击。它也可以通过命令行在无头环境中运行。
- 灵活– 使用 Python 配置攻击。这可以处理复杂的要求,例如签名请求和多步攻击序列。此外,自定义 HTTP 堆栈意味着它可以处理破坏其他库的格式错误的请求。
- 方便– 可以通过改编自Backslash Powered Scanner的高级差异算法自动过滤掉无用的结果。这意味着您可以发起攻击并通过两次点击获得有用的结果。
另一方面,它无疑更难使用,并且网络堆栈不像核心 Burp 那样可靠和经过实战测试。最后,我应该提到它是为向单个主机发送大量请求而设计的。如果你想向很多主机发送一个请求,我推荐ZGrab。
安装方法
使用 BApp Store 的 Extender 选项卡将 Turbo Intruder 安装到 Burp Suite。

如果您更喜欢从源代码构建它,请使用gradle build fatJar然后通过Extender->Extensions->Add加载src/build/libs/turbo-intruder-all.jar。
使用方法
要使用它,只需突出显示要注入的区域,然后右键单击并“发送到 Turbo Intruder”:

这将打开一个窗口,其中包含您的请求和如下所示的 Python 代码段:

您可以根据要通过攻击实现的目标自定义此代码。

基本使用
您会注意到您突出显示的请求区域已替换为“%s”——这是您的payloads将被放置的位置。首先,您可能只想将“/usr/share/dict/words”更改为更合适的字典。除此之外,对于简单的用例,默认脚本应该是开箱即用的。您可以使用 ctrl+enter 启动/停止攻击。
注意事项
Turbo Intruder 通过网络级效率实现速度,因此即使在网络连接不佳的情况下,它也应保持相对性能;我的第一个现场演示是在酒吧地下室使用从隔壁咖啡店借来的 wifi 完成的,并且仍然达到每秒几百个请求。
这意味着目标网站可能会成为其运行速度的限制因素。由于它使用的并发连接数较少,因此不太可能导致典型的 DoS 情况,即服务器的连接池已被消耗而其他人无法连接。然而,针对资源密集型页面可能会使服务器陷入困境并降低每个人的速度,因此建议在攻击期间监控应用程序性能。
过滤无聊的结果
在 Turbo Intruder 中,响应不会自动放置在结果表中。相反,将调用“handleResponse”函数,您可以在其中决定是否将响应添加到表中。这是一个简单的例子:
def handleResponse(req, interesting):
if '200 OK' in req.response:
table.add(req)
在这里编写自定义响应检查并不总是必要的 – 如果您使用“学习”参数将一些请求排入队列,那么 Turbo Intruder 会将这些响应视为无聊,然后根据每个新响应是否看起来像设置“有趣”参数一个无聊的。默认脚本使用此策略。有关此过滤策略的更多信息,请查看我关于 Backslash Powered Scanner 的演示文稿。
如果您想根据响应属性定义自己的过滤器,可以使用装饰器轻松实现:
@MatchStatus(200,204)
@MatchSizeRange(100,1000)
def handleResponse(req, interesting):
table.add(req)
有关此方法的更多信息,请查看完整的装饰器文档。
调速
如果速度对您的攻击很重要,您将需要调整pipeline、requestsPerConnection和concurrentConnections参数,可能按此顺序。您的目标应该是找到最大化 RPS(每秒请求数)值的值,同时保持重试次数计数器接近 0。此处的最佳值高度依赖于服务器,但到目前为止我已达到远程服务器的最大速度是 30,000 RPS。您可以通过减少请求和/或通过将方法从 GET 更改为 HEAD 来缩短响应来进一步提高速度。
寻找竞争条件
默认脚本使用流攻击风格,这对于最小化内存使用非常有用,但对于查找竞争条件并不理想。要找到竞争条件,您需要确保所有请求都在尽可能小的窗口内达到目标,这可以使用Race.py 中演示的专门构建的“门”系统来 实现。
有关使用 Turbo Intruder 查找竞争条件的真实示例,请查看 AWS Cognito 中的密码重置代码暴力破解漏洞。
内置字典
Turbo Intruder 有两个内置的字典——一个用于发起长时间运行的蛮力攻击,另一个包含在范围内代理流量中观察到的所有词。后一个字典可能会导致一些非常有趣的发现,这些发现通常需要手动测试才能识别。您可以在specialWordlists.py 中了解如何使用这些 。
命令行使用
有时,您可能会发现想要从服务器运行 Turbo Intruder。为了支持无头使用,它可以直接从 jar 启动,无需 Burp。
你可能会发现像往常一样在 Burp 中开发你的脚本最容易,然后保存并在服务器上启动它:
java -jar turbo.jar <脚本文件> <baseRequestFile> <endpoint> <baseInput>
例子:
java -jar turbo.jar resources/examples/basic.py resources/examples/request.txt https://example.net:443 foo
命令行支持非常基本 – 如果您尝试专门使用它,您可能会遇到麻烦。此外,它不支持自动有趣的响应检测,因为这依赖于各种 Burp 方法。
交换请求引擎
Turbo Intruder 的架构使您可以轻松地在不同的网络堆栈之间交换,使用 RequestEngine 的可选“引擎”参数。默认情况下,它将使用快速的 Engine.THREADED 选项,但在某些情况下,您可能更喜欢通过使用 Engine.BURP 来利用 Burp 的稳定性或上游代理处理。2021 年 8 月 24 日更新:我添加了一个自定义 HTTP/2 堆栈作为 Engine.HTTP2 可用,您还可以通过 Engine.BURP2 使用 Burp 的 HTTP/2 堆栈。
调试问题
如果统计面板中的“失败”计数器开始快速增加,这是出现问题的好兆头。这可能是您的脚本、目标网站或 Turbo Intruder 的网络堆栈的问题。如果您有兴趣帮助改进该工具,我已经制作了一个调试脚本来帮助您识别并可能报告问题的根源。
多个参数
您可以轻松地使用多个参数,只需将它们作为列表传入即可。
多主机攻击
每个请求引擎只能与一个 TCP 端点对话,但是如果您想向多个网站发送请求,您可以通过创建多个请求引擎来实现这一点。Turbo Intruder 的设计考虑了单主机攻击,同时打开大量 TCP 连接并不能很好地扩展。此外,统计面板仅反映一个请求引擎。我可能会在未来的某个时候解决这个问题,但现在,如果您想向大量主机发送少量请求,我建议使用 ZGrab。
攻击状态
当您学习编写更高级的攻击时,您可能希望跟踪请求之间的状态。请求引擎有一个名为 userState 的字典,您可以使用它。我编写了一个示例脚本,演示如何使用此功能通过计时攻击枚举用户名。
更多例子
要了解 Turbo Intruder 中可用的其他高级功能,请查看示例脚本的完整列表。
编辑器设置
您可以通过设置菜单自定义一些编辑器设置,如行号和字体大小:

最后说明
与以往一样,我对 Turbo Intruder 的未来改进有很多计划。我们也期待最终将 Turbo Intruder 网络堆栈中的一些功能引入核心 Burp Suite 工具中。
祝你好运,玩得开心,尽量不要拿下/攻击任何东西。
介绍完了,有不清楚的可以到官网查看
portswigger.net/research/turbo-intruder-embracing-the-billion-request-attack
Turbo Intruder Decorators
Decorators响应

Turbo Intruder 为研究人员提供了整个 Python 语言的强大功能来描述如何发出 HTTP 请求以及如何处理 HTTP 响应。但是,由于该语言非常灵活,因此某些代码模式通常用于各种响应处理场景。用户可能想要根据各种标准匹配或过滤响应是一种常见的做法。例如,用户可能只想根据与特定正则表达式或 HTTP 状态代码匹配的响应内容来处理响应。相反,用户可能希望根据特定的正则表达式或状态代码过滤掉响应。这些操作中的每一个都需要编写和粘贴各种handleResponse
函数实现来满足这些期望的目标。像ffuf
和这样的工具dirsearch
有简单的方法来启用这些匹配器和过滤器,不幸的是 Turbo Intruder 没有,它留给用户编写这些实现。通过此更新,Turbo Intruder 应包含插件内置的匹配器和过滤器实现,以使所有用户能够轻松地向其实现添加/删除复杂的匹配器和过滤器逻辑handleResponse
。
Decorators响应例子
假设我们只想查看状态为 200 和 204 的响应,用户可以编写如下所示的实现:
@MatchStatus(200,204)
def handleResponse(req, interesting):
table.add(req)
相反,他们可能希望查看除 200 和 204 之外的所有其他状态的所有响应
@FilterStatus(200,204)
def handleResponse(req, interesting):
table.add(req)
Python 装饰器可以堆叠在一起,并从上到下进行评估。让我们继续匹配所有响应状态 200 和 204,但仅匹配 100 到 1000 字节之间的那些响应
@MatchStatus(200,204)
@MatchSizeRange(100,1000)
def handleResponse(req, interesting):
table.add(req)
也许我们想使用正则表达式来帮助一些 cookie 匹配
@MatchRegex(r".*Set-Cookie.*")
@MatchRegex(r".*SECRETCOOKIENAME.*")
def handleResponse(req, interesting):
table.add(req)
或者我们想过滤掉讨厌的 200 Not Founds
@MatchStatus(200)
@FilterRegex(r".*Not Found.*")
def handleResponse(req, interesting):
table.add(req)
支持的Decorators响应列表
Decorators | 描述 |
---|---|
@MatchStatus(StatusCode, …) | 匹配具有 1 个或多个指定状态代码的响应 |
@FilterStatus(StatusCode, …) | 过滤具有 1 个或多个指定状态代码的响应 |
@MatchSize(RawSize, …) | 匹配具有 1 个或多个指定响应大小的响应 |
@FilterSize(RawSize, …) | 过滤具有 1 个或多个指定响应大小的响应 |
@MatchSizeRange(min, max) | 匹配大小介于 min 和 max(含)之间的响应 |
@FilterSizeRange(min, max) | 过滤大小介于最小和最大(含)之间的响应 |
@MatchWordCount(WordCount, …) | 匹配具有 1 个或多个指定响应字数的响应 |
@FilterWordCount(WordCount, …) | 过滤具有 1 个或多个指定响应字数的响应 |
@MatchWordCountRange(min, max) | 匹配字数介于 min 和 max(含)之间的响应 |
@FilterWordCountRange(min, max) | 过滤字数介于最小和最大(含)之间的响应 |
@MatchLineCount(LineCount, …) | 匹配具有 1 个或多个指定响应行数的响应 |
@FilterLineCount(LineCount, …) | 过滤具有 1 个或多个指定响应行数的响应 |
@MatchLineCountRange(min, max) | 匹配行数介于 min 和 max (含)之间的响应 |
@FilterLineCountRange(min, max) | 过滤行数介于 min 和 max (含)之间的响应 |
@MatchRegex(expression) | 匹配匹配指定正则表达式的响应(不区分大小写) |
@FilterRegex(expression) | 过滤与指定正则表达式匹配的响应(不区分大小写) |
@UniqueSize(instances=1) | 只允许通过 N 个具有给定状态/大小的响应实例 |
@UniqueWordCount(instances=1) | 仅允许通过 N 个具有给定状态/字数的响应实例 |
@UniqueLineCount(instances=1) | 仅允许通过 N 个具有给定状态/行数的响应实例 |