Ejemplo n.º 1
0
def brute_force_containers(storage_accounts, brute_list, threads):
    """
    Attempts to find public Blob Containers in valid Storage Accounts

    Here is the URL format to list Azure Blog Container contents:
    <account>.blob.core.windows.net/<container>/?restype=container&comp=list
    """

    # We have a list of valid DNS names that might not be worth scraping,
    # such as disabled accounts or authentication required. Let's quickly
    # weed those out.
    print(
        f"[*] Checking {len(storage_accounts)} accounts for status before brute-forcing"
    )
    valid_accounts = []
    for account in storage_accounts:
        try:
            reply = requests.get(f'https://{account}/')
            if 'Server failed to authenticate the request' in reply.reason:
                storage_accounts.remove(account)
            elif 'The specified account is disabled' in reply.reason:
                storage_accounts.remove(account)
            else:
                valid_accounts.append(account)
        except requests.exceptions.ConnectionError as error_msg:
            print(f"    [!] Connection error on https://{account}:")
            print(error_msg)

    # Read the brute force file into memory
    clean_names = utils.get_brute(brute_list, mini=3)

    # Start a counter to report on elapsed time
    start_time = utils.start_timer()

    print(
        f"[*] Brute-forcing container names in {len(valid_accounts)} storage accounts"
    )
    for account in valid_accounts:
        print(
            f"[*] Brute-forcing {len(clean_names)} container names in {account}"
        )

        # Initialize the list of correctly formatted urls
        candidates = []

        # Take each mutated keyword and craft a url with correct format
        for name in clean_names:
            candidates.append(f'{account}/{name}/?restype=container&comp=list')

        # Send the valid names to the batch HTTP processor
        utils.get_url_batch(candidates,
                            use_ssl=True,
                            callback=print_container_response,
                            threads=threads)

    # Stop the timer
    utils.stop_timer(start_time)
Ejemplo n.º 2
0
def check_functions(names, brute_list, quickscan, threads):
    """
    Checks for Google Cloud Functions running on cloudfunctions.net

    This is a two-part process. First, we want to find region/project combos
    that have existing Cloud Functions. The URL for a function looks like this:
    https://[ZONE]-[PROJECT-ID].cloudfunctions.net/[FUNCTION-NAME]

    We look for a 302 in [ZONE]-[PROJECT-ID].cloudfunctions.net. That means
    there are some functions defined in that region. Then, we brute force a list
    of possible function names there.

    See gcp_regions.py to define which regions to check. The tool currently
    defaults to only 1 region, so you should really modify it for best results.
    """
    print("[+] Checking for project/zones with Google Cloud Functions.")

    # Start a counter to report on elapsed time
    start_time = utils.start_timer()

    # Pull the regions from a config file
    regions = gcp_regions.REGIONS

    print(
        f"[*] Testing across {len(regions)} regions defined in the config file"
    )

    for region in regions:
        # Initialize the list of initial URLs to check
        candidates = [region + '-' + name + '.' + FUNC_URL for name in names]

    # Send the valid names to the batch HTTP processor
    utils.get_url_batch(candidates,
                        use_ssl=False,
                        callback=print_functions_response1,
                        threads=threads,
                        redir=False)

    # Retun from function if we have not found any valid combos
    if not HAS_FUNCS:
        utils.stop_timer(start_time)
        return

    # Also bail out if doing a quick scan
    if quickscan:
        return

    # If we did find something, we'll use the brute list. This will allow people
    # to provide a separate fuzzing list if they choose.
    print(
        f"[*] Brute-forcing function names in {len(HAS_FUNCS)} project/region combos"
    )

    # Load brute list in memory, based on allowed chars/etc
    brute_strings = utils.get_brute(brute_list)

    # The global was built in a previous function. We only want to brute force
    # project/region combos that we know have existing functions defined
    for func in HAS_FUNCS:
        print(
            f"[*] Brute-forcing {len(brute_strings)} function names in {func}")
        # Initialize the list of initial URLs to check. Strip out the HTTP
        # protocol first, as that is handled in the utility
        func = func.replace("http://", "")

        # Noticed weird behaviour with functions when a slash is not appended.
        # Works for some, but not others. However, appending a slash seems to
        # get consistent results. Might need further validation.
        candidates = [func + brute + '/' for brute in brute_strings]

        # Send the valid names to the batch HTTP processor
        utils.get_url_batch(candidates,
                            use_ssl=False,
                            callback=print_functions_response2,
                            threads=threads)

    # Stop the time
    utils.stop_timer(start_time)
Ejemplo n.º 3
0
def brute_force_containers(storage_accounts,
                           brute_list,
                           threads,
                           cverbose=True):
    """
    Attempts to find public Blob Containers in valid Storage Accounts

    Here is the URL format to list Azure Blog Container contents:
    <account>.blob.core.windows.net/<container>/?restype=container&comp=list
    """

    # We have a list of valid DNS names that might not be worth scraping,
    # such as disabled accounts or authentication required. Let's quickly
    # weed those out.
    if cverbose:
        print(
            "[*] Checking {} accounts for status before brute-forcing".format(
                len(storage_accounts)))
    pname = ['Azure Containers', 4]
    valid_accounts = []
    for account in storage_accounts:
        reply = requests.get('https://{}/'.format(account))
        if 'Server failed to authenticate the request' in reply.reason:
            storage_accounts.remove(account)
        elif 'The specified account is disabled' in reply.reason:
            storage_accounts.remove(account)
        else:
            valid_accounts.append(account)

    # Read the brute force file into memory
    clean_names = utils.get_brute(brute_list, mini=3)

    # Start a counter to report on elapsed time
    start_time = utils.start_timer()

    if cverbose:
        print(
            "[*] Brute-forcing container names in {} storage accounts".format(
                len(valid_accounts)))
    for c, account in enumerate(valid_accounts):
        pname[1] = '4.{}'.format(c)
        if cverbose:
            print("[*] Brute-forcing {} container names in {}".format(
                len(clean_names), account))

        # Initialize the list of correctly formatted urls
        candidates = []

        # Take each mutated keyword and craft a url with correct format
        for name in clean_names:
            candidates.append('{}/{}/?restype=container&comp=list'.format(
                account, name))

        # Send the valid names to the batch HTTP processor
        utils.get_url_batch(candidates,
                            pname,
                            cverbose,
                            use_ssl=True,
                            callback=print_container_response,
                            threads=threads)

    # Stop the timer
    utils.stop_timer(start_time, cverbose)