保姆级并发教程(Turbo Intruder)

并发在src圈很火,所谓万物皆可并发,在日常漏洞挖掘过程中遇到的概率还是非常高的,最常用的方式就是利用Burpsuite的Turbo Intruder插件,但仅仅使用到单一并发,网上大部分的教程也是如此,这次来个大起底,围绕着此插件对并发实践进行一个详细的讲解。

0x01 并发

并发与条件竞争

提到并发,就会想起条件竞争漏洞。并发漏洞是由于多个线程或进程同时访问共享资源而导致的安全问题,条件竞争漏洞是由于事件发生的顺序或时机引发的安全问题。在安全领域,”并发漏洞”的范围更大,因为它涵盖了更广泛的并发环境下可能出现的安全问题,包括但不限于数据竞争、死锁、活锁等。与之相比,条件竞争漏洞是并发漏洞的一个特定子类,它更专注于安全性依赖于事件发生的顺序或时机这一特定问题。

并发与重放

之前有个师傅问过一个问题,BurpSuite已经有了intruder模块为什么还要用这个插件,问题的原因就是并发是指的是抢在同一时间发送所有数据包,而intruder模块是无法做到的。

0x02 实践

Turbo Intruder介绍

“Turbo Intruder”是一个用于Web应用程序渗透测试的工具,它是Burp Suite的一个插件,用于进行高效的并发HTTP请求。Burp Suite是一个流行的Web应用程序渗透测试工具集,而Turbo Intruder则是其中的一个功能强大的插件。

Turbo Intruder的主要功能包括:

  • 高效的并发请求:能够同时发送大量的HTTP请求。
  • 定制化的Payload:可以定制HTTP请求的Payload,支持字典攻击、暴力破解等多种方式。
  • 高级的响应分析:可以分析HTTP响应,识别潜在的漏洞。
  • 自定义脚本:支持编写自定义的Python脚本,以扩展其功能。
    使用Turbo Intruder可以帮助安全研究人员和渗透测试人员发现Web应用程序中的安全漏洞,如注入攻击、身份验证问题、逻辑漏洞等。

安装

Burpsuite->Extensions->BApp Store->Turbo intruder->install

项目地址

基本操作

适合对同一数据包进行不变换参数并发操作
选择数据包->Extensions->Turbo Intruder

打开一个包含您的请求和 Python 代码片段的窗口,如下所示(不同的版本,内附脚本是不同,文中示例版本为v1.0.19),数据包上面添加%s(也可以新加一个请求头req: %s),下面选择examples/race.py

并发请求成功返回的状态码均为200

进阶操作

这里其实就是选择不同的paylaod,实现不同的效果,例同一数据包,变换参数并发请求

  • 这种场景大家可以思考下,在挖src时候,有个并发赠送其他账户优惠券的漏洞,仅使用单一并发请求,发现其他账户只收到了一张优惠券,这个时候若在并发时候修改他的账号的id,即可实现将优惠券赠送到多个账户,扩大危害✔
  • 场景二是新人优惠购时,单一并发请求,你会发现仅仅可能只会购买一次,但是通过修改并发时候的参数就会购买多次,扩大危害✔
  • ……

学会这种’变形’并发是非常有必要的,下面就具体介绍:

单参数

首先了解payload的含义,以examples/basic.py为例

代码如下:

def queueRequests(target, wordlists):
    # 初始化请求引擎
    engine = RequestEngine(endpoint=target.endpoint,
                           concurrentConnections=5,  # 并发连接数
                           requestsPerConnection=100,  # 每个连接的请求数
                           pipeline=False  # 管道模式
                           )

    # 逐行读取字典文件中的单词并构造请求
    for word in open('/usr/share/dict/words'):
        engine.queue(target.req, word.rstrip())  # 将请求添加到队列中

def handleResponse(req, interesting):
    # 处理从服务器接收到的响应
    # 如果响应状态码不是 404,则将请求添加到表中
    if req.status != 404:
        table.add(req)

将代码中的字典文件路径/usr/share/dict/words修改为D:\dicts.txt,在请求中需要替换参数地方加上%s,如果请求为HTTP/2的改为HTTP/1.1:

此前分享的FOFA高级查询,设置的策略是每 15 秒只能请求一次,但通过并发成功突破此限制(文末附练习靶场)

多参数

只需要修改下内置examples/basic.py如下即可,这里以双参数并发举例,更多参数并发同理即可:

def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                           concurrentConnections=5,
                           requestsPerConnection=100,
                           pipeline=False)
    #增加参数修改此处代码                       
    for page in open('D:\dicts2.txt'):
         for limit in open('D:\dicts.txt'):
             engine.queue(target.req, [page.rstrip(), limit.rstrip()])

def handleResponse(req, interesting):
    # currently available attributes are req.status, req.wordcount, req.length and req.response
    if req.status != 404:
        table.add(req)

成功突破限制,多参数并发成功:

0x03 经验总结

加密并发

是不是有很多师傅觉得加密的参数就无法并发了,但其实通过上面的方法,只需要将加密的参数放到dicts.txt即可

HTTP2问题

虽然上面通过修改请求头为HTTP/1.1可以正常并发,但是有的网站并不支持HTTP/1.1访问,这个时候需要下载最新版Turbo Intruder,笔者测试时候使用的是v1.42,需要将basic.py代码中的pipeline=False替换为engine=Engine.HTTP2

成功使用HTTP2并发请求:

利用场景

在文章开篇时已经提到了,万物即可并发,就是目前所有的功能点都可以并发,短信并发、优惠券并发、下单并发、支付并发、删除并发……甚至连文件上传都可以并发,所谓是大力出奇迹!

漏洞修复

下面列出部分修复漏洞的方法:

  • 使用同步机制:在关键的代码段中使用同步机制来确保在同一时间只有一个线程可以访问共享资源。可以使用Java中的synchronized关键字或者ReentrantLock来实现同步。
  • 使用事务管理:对于涉及到数据库操作的情况,使用Spring的事务管理机制来确保数据库操作的原子性和一致性。通过将相关操作放在事务中,可以避免在并发情况下出现数据不一致的问题。
  • 使用乐观锁或悲观锁:在需要对共享资源进行更新的地方,可以考虑使用乐观锁或悲观锁来控制并发访问。乐观锁基于版本号或时间戳,而悲观锁则是在操作前获取锁。Spring Data JPA和Hibernate等持久化框架提供了对乐观锁的支持。
  • 使用并发安全的数据结构:在需要使用共享数据结构的地方,使用并发安全的数据结构,如ConcurrentHashMap,可以减少并发访问带来的风险。
  • 限制并发访问:可以通过限制同时访问某些资源的线程数或者请求频率来减少并发访问的压力。例如,使用限流算法或者队列来控制请求的处理速率。
  • 使用分布式锁:如果应用是分布式的,考虑使用分布式锁来保护关键资源,以避免不同节点之间的并发冲突。Redisson等分布式锁的实现可以帮助解决这个问题。

因本地环境使用了redis,所以使用Redisson分布式锁,修复了此漏洞,具体代码如下:

    // 获取分布式锁
    RLock lock = redisson.getLock("myLock");

    try {
        // 尝试获取锁,最多等待10秒,锁的持有时间为30秒
        boolean isLocked = lock.tryLock(10, 30, TimeUnit.SECONDS);
        if (isLocked) {
            // 成功获取锁后执行业务逻辑
            System.out.println("成功获取锁,执行业务逻辑...");
            Thread.sleep(5000); // 模拟业务处理时间
        } else {
            // 获取锁失败
            System.out.println("获取锁失败,可能有其他线程持有锁或者超时");
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        // 释放锁
        lock.unlock();
        System.out.println("锁已释放");
    }

    // 关闭Redisson客户端
    redisson.shutdown();
    }

再次并发请求,发现成功的请求只有一次:

坑点

这个时候我把代码部署到了服务器,并发又成功了:

可以看下图,通过了3个请求:

通过反复分析,找到了问题的关键就是cdn,在高并发的场景下会有接口缓存机制,这个在通过分析返回请求发现的,无论limit参数在并发时设置的多少,返回的数据均是相同的:

0x04 完结

为了方便各位师傅练习,FOFA高级在线查询(FOFA(技巧)是个好东西,真希望人人都有)的问题虽然已经修复了,但是提供了一个练习版本,关注公众号回复:并发,即可获取靶场及本文所用到的工具和代码。

免责声明

免责声明:本博客的内容仅供合法、正当、健康的用途,切勿将其用于违反法律法规的行为。如因此导致任何法律责任或纠纷,本博客概不负责。谢谢您的理解与配合!

本文链接:

https://sanshiok.com/archive/16.html

# 最新文章