def print_s3_response(reply): """ Parses the HTTP reply of a brute-force attempt This function is passed into the class object so we can view results in real-time. """ data = {'platform': 'aws', 'msg': '', 'target': '', 'access': ''} if reply.status_code == 404: pass elif 'Bad Request' in reply.reason: pass elif reply.status_code == 200: data['msg'] = 'OPEN S3 BUCKET' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) utils.list_bucket_contents(reply.url) elif reply.status_code == 403: data['msg'] = 'Protected S3 Bucket' data['target'] = reply.url data['access'] = 'protected' utils.fmt_output(data) elif 'Slow Down' in reply.reason: print("[!] You've been rate limited, skipping rest of check...") return 'breakout' else: print(f" Unknown status codes being received from {reply.url}:\n" " {reply.status_code}: {reply.reason}") return None
def print_bucket_response(reply): """ Parses the HTTP reply of a brute-force attempt This function is passed into the class object so we can view results in real-time. """ data = {'platform': 'gcp', 'msg': '', 'target': '', 'access': ''} if reply.status_code == 404: pass elif reply.status_code == 200: data['msg'] = 'OPEN GOOGLE BUCKET' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) utils.list_bucket_contents(reply.url + '/') elif reply.status_code == 403: data['msg'] = 'Protected Google Bucket' data['target'] = reply.url data['access'] = 'protected' utils.fmt_output(data) else: print(f" Unknown status codes being received from {reply.url}:\n" " {reply.status_code}: {reply.reason}")
def print_vm_response(hostname): """ This function is passed into the DNS brute force as a callback, so we can get real-time results. """ data = {'platform': 'azure', 'msg': '', 'target': '', 'access': ''} data['msg'] = 'Registered Azure Virtual Machine DNS Name' data['target'] = hostname data['access'] = 'public' utils.fmt_output(data)
def print_fbrtdb_response(reply): """ Parses the HTTP reply of a brute-force attempt This function is passed into the class object so we can view results in real-time. """ data = {'platform': 'gcp', 'msg': '', 'target': '', 'access': ''} if reply.status_code == 404: pass elif reply.status_code == 200: data['msg'] = 'OPEN GOOGLE FIREBASE RTDB' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) elif reply.status_code == 401: data['msg'] = 'Protected Google Firebase RTDB' data['target'] = reply.url data['access'] = 'protected' utils.fmt_output(data) elif reply.status_code == 402: data['msg'] = 'Payment required on Google Firebase RTDB' data['target'] = reply.url data['access'] = 'disabled' utils.fmt_output(data) elif reply.status_code == 423: data['msg'] = 'The Firebase database has been deactivated.' data['target'] = reply.url data['access'] = 'disabled' utils.fmt_output(data) else: print(f" Unknown status codes being received from {reply.url}:\n" " {reply.status_code}: {reply.reason}")
def print_account_response(reply): """ Parses the HTTP reply of a brute-force attempt This function is passed into the class object so we can view results in real-time. """ data = {'platform': 'azure', 'msg': '', 'target': '', 'access': ''} if reply.status_code == 404: pass elif 'Server failed to authenticate the request' in reply.reason: data['msg'] = 'Auth-Only Storage Account' data['target'] = reply.url data['access'] = 'protected' utils.fmt_output(data) elif 'The specified account is disabled' in reply.reason: data['msg'] = 'Disabled Storage Account' data['target'] = reply.url data['access'] = 'disabled' utils.fmt_output(data) elif 'Value for one of the query' in reply.reason: data['msg'] = 'HTTP-OK Storage Account' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) elif 'The account being accessed' in reply.reason: data['msg'] = 'HTTPS-Only Storage Account' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) else: print(" Unknown status codes being received from {reply.url}:\n" " {reply.status_code}: {reply.reason}")
def print_container_response(reply): """ Parses the HTTP reply of a brute-force attempt This function is passed into the class object so we can view results in real-time. """ data = {'platform': 'azure', 'msg': '', 'target': '', 'access': ''} # Stop brute forcing disabled accounts if 'The specified account is disabled' in reply.reason: print(" [!] Breaking out early, account disabled.") return 'breakout' # Stop brute forcing accounts without permission if ('not authorized to perform this operation' in reply.reason or 'not have sufficient permissions' in reply.reason or 'Public access is not permitted' in reply.reason or 'Server failed to authenticate the request' in reply.reason): print(" [!] Breaking out early, auth required.") return 'breakout' # Stop brute forcing unsupported accounts if 'Blob API is not yet supported' in reply.reason: print(" [!] Breaking out early, Hierarchical namespace account") return 'breakout' # Handle other responses if reply.status_code == 404: pass elif reply.status_code == 200: data['msg'] = 'OPEN AZURE CONTAINER' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) utils.list_bucket_contents(reply.url) elif 'One of the request inputs is out of range' in reply.reason: pass elif 'The request URI is invalid' in reply.reason: pass else: print(f" Unknown status codes being received from {reply.url}:\n" " {reply.status_code}: {reply.reason}") return None
def print_functions_response1(reply): """ Parses the HTTP reply the initial Cloud Functions check This function is passed into the class object so we can view results in real-time. """ data = {'platform': 'gcp', 'msg': '', 'target': '', 'access': ''} if reply.status_code == 404: pass elif reply.status_code == 302: data['msg'] = 'Contains at least 1 Cloud Function' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) HAS_FUNCS.append(reply.url) else: print(f" Unknown status codes being received from {reply.url}:\n" " {reply.status_code}: {reply.reason}")
def print_functions_response2(reply): """ Parses the HTTP reply from the secondary, brute-force Cloud Functions check This function is passed into the class object so we can view results in real-time. """ data = {'platform': 'gcp', 'msg': '', 'target': '', 'access': ''} if 'accounts.google.com/ServiceLogin' in reply.url: pass elif reply.status_code in (403, 401): data['msg'] = 'Auth required Cloud Function' data['target'] = reply.url data['access'] = 'protected' utils.fmt_output(data) elif reply.status_code == 405: data['msg'] = 'UNAUTHENTICATED Cloud Function (POST-Only)' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) elif reply.status_code in (200, 404): data['msg'] = 'UNAUTHENTICATED Cloud Function (GET-OK)' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) else: print(f" Unknown status codes being received from {reply.url}:\n" " {reply.status_code}: {reply.reason}")
def print_appspot_response(reply): """ Parses the HTTP reply of a brute-force attempt This function is passed into the class object so we can view results in real-time. """ data = {'platform': 'gcp', 'msg': '', 'target': '', 'access': ''} if reply.status_code == 404: pass elif str(reply.status_code)[0] == 5: data['msg'] = 'Google App Engine app with a 50x error' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) elif reply.status_code in (200, 302, 404): if 'accounts.google.com' in reply.url: data['msg'] = 'Protected Google App Engine app' data['target'] = reply.history[0].url data['access'] = 'protected' utils.fmt_output(data) else: data['msg'] = 'Open Google App Engine app' data['target'] = reply.url data['access'] = 'public' utils.fmt_output(data) else: print(f" Unknown status codes being received from {reply.url}:\n" " {reply.status_code}: {reply.reason}")
def check_awsapps(names, threads, nameserver): """ Checks for existence of AWS Apps (ie. WorkDocs, WorkMail, Connect, etc.) """ data = { 'platform': 'aws', 'msg': 'AWS App Found:', 'target': '', 'access': '' } print("[+] Checking for AWS Apps") # Start a counter to report on elapsed time start_time = utils.start_timer() # Initialize the list of domain names to look up candidates = [] # Initialize the list of valid hostnames valid_names = [] # Take each mutated keyword craft a domain name to lookup. for name in names: candidates.append(f'{name}.{APPS_URL}') # AWS Apps use DNS sub-domains. First, see which are valid. valid_names = utils.fast_dns_lookup(candidates, nameserver, threads=threads) for name in valid_names: data['target'] = f'https://{name}' data['access'] = 'protected' utils.fmt_output(data) # Stop the timer utils.stop_timer(start_time)