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)
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)
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)