def _get_rbp(self) -> ResponseGetRbp: """Get the resource based policy for this resource and store it""" logger.debug("Getting resource policy for %s" % self.arn) try: response = self.client.get_resource_policy(SecretId=self.name) if response.get("ResourcePolicy"): policy = json.loads(response.get("ResourcePolicy")) else: policy = constants.get_empty_policy() success = True except botocore.exceptions.ClientError: # When there is no policy, let's return an empty policy to avoid breaking things policy = constants.get_empty_policy() success = False policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self. override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def _get_rbp(self) -> ResponseGetRbp: """Get the resource based policy for this resource and store it""" logger.debug("Getting resource policy for %s" % self.arn) # When there is no policy, let's return an empty policy to avoid breaking things policy = constants.get_empty_policy() try: response = self.client.get_topic_attributes(TopicArn=self.arn) attributes = response.get("Attributes") if attributes.get("Policy"): policy = constants.get_empty_policy() policy["Statement"].extend( json.loads(attributes.get("Policy")).get("Statement")) else: policy = constants.get_empty_policy() success = True except self.client.exceptions.ResourceNotFoundException as error: logger.critical(error) success = False except botocore.exceptions.ClientError as error: logger.critical(error) success = False policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self. override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def _get_rbp(self) -> ResponseGetRbp: """Get the resource based policy for this resource and store it""" logger.debug("Getting resource policy for %s" % self.arn) try: # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ses.html#SES.Client.list_identity_policies response = self.client.describe_elasticsearch_domain_config(DomainName=self.name) domain_config = response.get("DomainConfig") policy = domain_config.get("AccessPolicies").get("Options") if policy: policy = json.loads(policy) else: policy = constants.get_empty_policy() success = True except botocore.exceptions.ClientError: # When there is no policy, let's return an empty policy to avoid breaking things policy = constants.get_empty_policy() success = False policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self.override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def _get_rbp(self) -> ResponseGetRbp: """Get the resource based policy for this resource and store it""" # If you do not know the names of the policies that are attached to the identity, you can use ListIdentityPolicies logger.debug("Getting resource policy for %s" % self.arn) # When there is no policy, let's return an empty policy to avoid breaking things policy = constants.get_empty_policy() try: # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ses.html#SES.Client.list_identity_policies response = self.client.list_identity_policies(Identity=self.name) # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ses.html#SES.Client.get_identity_policies policy_names = response.get("PolicyNames") if policy_names: response = self.client.get_identity_policies(Identity=self.name, PolicyNames=policy_names) policies = response.get("Policies") if constants.SID_SIGNATURE in policies: policy = json.loads(policies.get(constants.SID_SIGNATURE)) success = True else: policy = constants.get_empty_policy() success = True except botocore.exceptions.ClientError: success = False policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self.override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def _get_rbp(self) -> ResponseGetRbp: """Get the resource based policy for this resource and store it""" # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/kms.html#KMS.Client.get_key_policy logger.debug("Getting resource policy for %s" % self.arn) try: response = self.client.get_key_policy(KeyId=self.arn, PolicyName="default") if response.get("Policy"): policy = constants.get_empty_policy() policy["Statement"].extend( json.loads(response.get("Policy")).get("Statement")) else: policy = constants.get_empty_policy() success = True except botocore.exceptions.ClientError: # When there is no policy, let's return an empty policy to avoid breaking things policy = constants.get_empty_policy() success = False policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self. override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def _get_rbp(self) -> ResponseGetRbp: """Get the resource based policy for this resource and store it""" logger.debug("Getting resource policy for %s" % self.arn) try: response = self.client.get_role(RoleName=self.name) policy = response.get("Role").get("AssumeRolePolicyDocument") success = True except self.client.exceptions.NoSuchEntityException: logger.critical(f"There is no resource with the name {self.name}") policy = constants.get_empty_policy() success = False except botocore.exceptions.ClientError: # When there is no policy, let's return an empty policy to avoid breaking things policy = constants.get_empty_policy() success = False policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self. override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def _get_rbp(self) -> ResponseGetRbp: """Get the resource based policy for this resource and store it""" logger.debug("Getting resource policy for %s" % self.arn) # When there is no policy, let's return an empty policy to avoid breaking things policy = constants.get_empty_policy() try: # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/glacier.html#Glacier.Client.get_vault_access_policy response = self.client.get_vault_access_policy(vaultName=self.name) policy = json.loads(response.get("policy").get("Policy")) success = True # This is silly. If there is no access policy set on the vault, then it returns the same error as if the vault didn't exist. except self.client.exceptions.ResourceNotFoundException as error: logger.debug(error) success = True except botocore.exceptions.ClientError: success = False policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self. override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def _get_rbp(self) -> ResponseGetRbp: """Get the resource based policy for this resource and store it""" logger.debug("Getting resource policy for %s" % self.arn) policy = constants.get_empty_policy() try: # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecr.html#ECR.Client.get_repository_policy response = self.client.get_repository_policy( repositoryName=self.name) policy = json.loads(response.get("policyText")) success = True except self.client.exceptions.RepositoryPolicyNotFoundException: logger.debug("Policy not found. Setting policy document to empty.") success = True except self.client.exceptions.RepositoryNotFoundException: logger.critical("Repository does not exist") success = False except botocore.exceptions.ClientError: # When there is no policy, let's return an empty policy to avoid breaking things success = False policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self. override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def _get_rbp(self) -> ResponseGetRbp: """Get the resource based policy for this resource and store it""" logger.debug("Getting resource policy for %s" % self.arn) policy = constants.get_empty_policy() try: response = self.client.get_bucket_policy(Bucket=self.name) policy = json.loads(response.get("Policy")) message = "200: Successfully obtained bucket policy for %s" % self.arn success = True except botocore.exceptions.ClientError as error: error_code = error.response['Error']['Code'] message = f"{error_code}: {error.response.get('Error').get('Message')} for {error.response.get('Error').get('BucketName')}" if error.response['Error']['Code'] == "AccessDenied": success = False elif error.response['Error']['Code'] == "NoSuchBucketPolicy": success = True else: # This occurs when there is no resource policy attached success = True except Exception as error: message = error success = False logger.debug(message) policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self. override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def _get_rbp(self) -> ResponseGetRbp: """Get the resource based policy for this resource and store it""" policy = constants.get_empty_policy() try: # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/acm-pca.html#ACMPCA.Client.get_policy response = self.client.get_policy(ResourceArn=self.arn) policy = json.loads(response.get("Policy")) success = True # This is dumb. "If either the private CA resource or the policy cannot be found, this action returns a ResourceNotFoundException." # That means we have to set it to true, even when the resource doesn't exist. smh. # That will only affect the expose command and not the smash command. except self.client.exceptions.ResourceNotFoundException: logger.debug(f"Resource {self.name} not found") success = True except botocore.exceptions.ClientError: # When there is no policy, let's return an empty policy to avoid breaking things success = False policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self. override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def undo(self, evil_principal: str, dry_run: bool = False) -> ResponseMessage: logger.debug(f"Removing {evil_principal} from {self.arn}") new_policy = constants.get_empty_policy() operation = "UNDO" if not dry_run: # TODO: After you delete the policy, it still shows up in resource shares. Need to delete that. # https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/acm-pca.html#ACMPCA.Client.delete_policy # TODO: Error handling for setting policy try: self.client.delete_policy(ResourceArn=self.arn) message = f"Deleted the resource policy for {self.arn}" success = True except botocore.exceptions.ClientError as error: success = False message = error logger.critical( f"Operation was not successful for {self.service} {self.resource_type} " f"{self.name}. %s" % error) else: message = f"The resource policy for {self.arn} will be deleted." success = True response_message = ResponseMessage( message=message, operation=operation, success=success, evil_principal=evil_principal, victim_resource_arn=self.arn, original_policy=self.original_policy, updated_policy=new_policy, resource_type=self.resource_type, resource_name=self.name, service=self.service) return response_message
def _get_rbp(self) -> ResponseGetRbp: logger.debug("Getting resource policy for %s" % self.arn) # When there is no policy, let's return an empty policy to avoid breaking things policy = constants.get_empty_policy() try: response = self.client.get_layer_version_policy( LayerName=self.name, VersionNumber=self.version) policy = json.loads(response.get("Policy")) success = True except self.client.exceptions.ResourceNotFoundException as error: logger.debug("The Policy does not exist. We will have to add it.") success = True except botocore.exceptions.ClientError as error: logger.critical(error) success = False policy_document = PolicyDocument( policy=policy, service=self.service, override_action=self.override_action, include_resource_block=self.include_resource_block, override_resource_block=self.override_resource_block, override_account_id_instead_of_principal=self. override_account_id_instead_of_principal, ) response = ResponseGetRbp(policy_document=policy_document, success=success) return response
def undo(self, evil_principal: str, dry_run: bool = False) -> ResponseMessage: """Wraps client.remove_permission""" logger.debug(f"Removing {evil_principal} from {self.arn}") new_policy = constants.get_empty_policy() operation = "UNDO" message = "404: No backdoor statement found" success = False for statement in self.policy_document.statements: if statement.sid == constants.SID_SIGNATURE: if not dry_run: # TODO: Error handling for setting policy self.client.remove_permission( QueueUrl=self.queue_url, Label=statement.sid, ) message = f"200: Removed backdoor statement from the resource policy attached to {self.arn}" success = True break else: new_policy["Statement"].append(json.loads(statement.__str__())) response_message = ResponseMessage( message=message, operation=operation, evil_principal=evil_principal, victim_resource_arn=self.arn, original_policy=self.original_policy, updated_policy=new_policy, resource_type=self.resource_type, resource_name=self.name, service=self.service, success=success) return response_message
def undo(self, evil_principal: str, dry_run: bool = False) -> ResponseMessage: """Wraps client.remove_permission""" logger.debug(f"Removing {evil_principal} from {self.arn}") new_policy = constants.get_empty_policy() operation = "UNDO" message = "404: No backdoor statement found" success = True for statement in self.policy_document.statements: if statement.sid == constants.SID_SIGNATURE: if not dry_run: try: self.client.remove_permission( FunctionName=self.name, StatementId=statement.sid, ) message = f"200: Removed backdoor statement from the resource policy attached to {self.arn}" success = True except botocore.exceptions.ClientError as error: success = False logger.critical(f"Operation was not successful for {self.service} {self.resource_type} " f"{self.name}. %s" % error) else: new_policy["Statement"].append(json.loads(statement.__str__())) response_message = ResponseMessage(message=message, operation=operation, success=success, evil_principal=evil_principal, victim_resource_arn=self.arn, original_policy=self.original_policy, updated_policy=new_policy, resource_type=self.resource_type, resource_name=self.name, service=self.service) return response_message