Domain-Protect - Protect Against Subdomain Takeover

Protect Against Subdomain Takeoverscans Amazon Route53 across an AWS Organization for domain records vulnerable to takeovervulnerable domains in Google Cloud DNS can be detected by Domain Protect for GCPdeploy to security audit accountscan your entire AWS Organizationreceive alerts by Slack or emailor manually scan from your laptopsubdomain detection functionalityScans Amazon Route53 to identify:Alias records for CloudFront distributions with missing S3 originCNAME records for CloudFront distributions with missing S3 originElasticBeanstalk Alias records vulnerable to takeoverElasticBeanstalk CNAMES vulnerable to takeoverRegistered domains with missing hosted zonesSubdomain NS delegations vulnerable to takeoverS3 Alias records vulnerable to takeoverS3 CNAMES vulnerable to takeoverVulnerable CNAME records for Azure resourcesCNAME records for missing Google Cloud Storage bucketsoptional additional checkTurned off by default as it may result in Lambda timeouts for large organisationsA records for missing storage buckets, e.g. Google Cloud Load Balancer with missing backend storageTo enable, create this Terraform variable in your tfvars file or CI/CD pipeline:lambdas = ["alias-cloudfront-s3", "alias-eb", "alias-s3", "cname-cloudfront-s3", "cname-eb", "cname-s3", "ns-domain", "ns-subdomain", "cname-azure", "cname-google", "a-storage"]optionsscheduled lambda functions with email and Slack alerts, across an AWS Organization, deployed using Terraformmanual scans run from your laptop or CloudShell, in a single AWS accountnotificationsSlack channel notification per vulnerability type, listing account names and vulnerable domainsEmail notification in JSON format with account names, account IDs and vulnerable domains by subscribing to SNS topicrequirementsSecurity audit account within AWS OrganizationsSecurity audit read-only role with an identical name in every AWS account of the OrganizationStorage bucket for Terraform state fileTerraform 1.0.xusagereplace the Terraform state S3 bucket fields in the command below as appropriatefor local testing, duplicate terraform.tfvars.example, rename without the .example suffixenter details appropriate to your organization and savealternatively enter Terraform variables within your CI/CD pipelineterraform init -backend-config=bucket=TERRAFORM_STATE_BUCKET -backend-config=key=TERRAFORM_STATE_KEY -backend-config=region=TERRAFORM_STATE_REGIONterraform workspace new devterraform planterraform applyAWS IAM policiesFor least privilege access control, example AWS IAM policies are provided:domain-protect audit policy - attach to domain-protect audit role in every AWS accountdomain-protect audit trust relationship for domain-protect audit role in every AWS accountdomain-protect audit trust relationship with External ID for domain-protect audit role in every AWS accountdomain-protect deploy policy - attach to IAM group or role assumed by CI/CD pipelineadding new checkscreate a new subdirectory within the terraform-modules/lambda/code directoryadd Python code file with same name as the subdirectoryadd the name of the file without extension to var.lambdas in variables.tfadd a subdirectory within the terraform-modules/lambda/build directory, following the existing naming patternadd a .gitkeep file into the new directoryupdate the .gitignore file following the pattern of existing directoriesapply Terraformadding notifications to extra Slack channelsadd an extra channel to your slack_channels variable listadd an extra webhook URL or repeat the same webhook URL to your slack_webhook_urls variable listapply Terraformtestinguse multiple Terraform workspace environments, e.g. dev, prduse the slack_channels_dev variable for your dev environment to notify a test Slack channelfor new subdomain takeover categories, create correctly configured and vulnerable domain names in Route53minimise the risk of malicious takeover by using a test domain, with domain names which are hard to enumerateremove any vulnerable domains as soon as possibleci/cdinfrastructure has been deployed using CircleCIenvironment variables to be entered in CircleCI project settings:ENVIRONMENT VARIABLEEXAMPLE VALUE / COMMENTAWS_ACCESS_KEY_IDusing domain-protect deploy policyAWS_SECRET_ACCESS_KEY-TERRAFORM_STATE_BUCKETtfstate48903TERRAFORM_STATE_KEYdomain-protectTERRAFORM_STATE_REGIONus-east-1TF_VAR_org_primary_account012345678901TF_VAR_security_audit_role_namenot needed if "domain-protect-audit" usedTF_VAR_external_idonly required if External ID is configuredTF_VAR_slack_channels["security-alerts"]TF_VAR_slack_channels_dev["security-alerts-dev"]TF_VAR_slack_webhook_urls["https://hooks.slack.com/services/XXX/XXX/XXX"]to validate an updated CircleCI configuration:docker run -v `pwd`:/whatever circleci/circleci-cli circleci config validate /whatever/.circleci/config.ymllimitationsthis tool cannot guarantee 100% protection against subdomain takeoverit currently only scans Amazon Route53, and only checks a limited number of takeover typesvu

Domain-Protect - Protect Against Subdomain Takeover


Protect Against Subdomain Takeover

  • scans Amazon Route53 across an AWS Organization for domain records vulnerable to takeover
  • vulnerable domains in Google Cloud DNS can be detected by Domain Protect for GCP

deploy to security audit account



scan your entire AWS Organization



receive alerts by Slack or email



or manually scan from your laptop



subdomain detection functionality

Scans Amazon Route53 to identify:

  • Alias records for CloudFront distributions with missing S3 origin
  • CNAME records for CloudFront distributions with missing S3 origin
  • ElasticBeanstalk Alias records vulnerable to takeover
  • ElasticBeanstalk CNAMES vulnerable to takeover
  • Registered domains with missing hosted zones
  • Subdomain NS delegations vulnerable to takeover
  • S3 Alias records vulnerable to takeover
  • S3 CNAMES vulnerable to takeover
  • Vulnerable CNAME records for Azure resources
  • CNAME records for missing Google Cloud Storage buckets

optional additional check

Turned off by default as it may result in Lambda timeouts for large organisations

  • A records for missing storage buckets, e.g. Google Cloud Load Balancer with missing backend storage

To enable, create this Terraform variable in your tfvars file or CI/CD pipeline:

lambdas = ["alias-cloudfront-s3", "alias-eb", "alias-s3", "cname-cloudfront-s3", "cname-eb", "cname-s3", "ns-domain", "ns-subdomain", "cname-azure", "cname-google", "a-storage"]

options
  1. scheduled lambda functions with email and Slack alerts, across an AWS Organization, deployed using Terraform
  2. manual scans run from your laptop or CloudShell, in a single AWS account

notifications
  • Slack channel notification per vulnerability type, listing account names and vulnerable domains
  • Email notification in JSON format with account names, account IDs and vulnerable domains by subscribing to SNS topic

requirements
  • Security audit account within AWS Organizations
  • Security audit read-only role with an identical name in every AWS account of the Organization
  • Storage bucket for Terraform state file
  • Terraform 1.0.x

usage
  • replace the Terraform state S3 bucket fields in the command below as appropriate
  • for local testing, duplicate terraform.tfvars.example, rename without the .example suffix
  • enter details appropriate to your organization and save
  • alternatively enter Terraform variables within your CI/CD pipeline
terraform init -backend-config=bucket=TERRAFORM_STATE_BUCKET -backend-config=key=TERRAFORM_STATE_KEY -backend-config=region=TERRAFORM_STATE_REGION
terraform workspace new dev
terraform plan
terraform apply

AWS IAM policies

For least privilege access control, example AWS IAM policies are provided:


adding new checks
  • create a new subdirectory within the terraform-modules/lambda/code directory
  • add Python code file with same name as the subdirectory
  • add the name of the file without extension to var.lambdas in variables.tf
  • add a subdirectory within the terraform-modules/lambda/build directory, following the existing naming pattern
  • add a .gitkeep file into the new directory
  • update the .gitignore file following the pattern of existing directories
  • apply Terraform

adding notifications to extra Slack channels
  • add an extra channel to your slack_channels variable list
  • add an extra webhook URL or repeat the same webhook URL to your slack_webhook_urls variable list
  • apply Terraform

testing
  • use multiple Terraform workspace environments, e.g. dev, prd
  • use the slack_channels_dev variable for your dev environment to notify a test Slack channel
  • for new subdomain takeover categories, create correctly configured and vulnerable domain names in Route53
  • minimise the risk of malicious takeover by using a test domain, with domain names which are hard to enumerate
  • remove any vulnerable domains as soon as possible

ci/cd
  • infrastructure has been deployed using CircleCI
  • environment variables to be entered in CircleCI project settings:
ENVIRONMENT VARIABLEEXAMPLE VALUE / COMMENT
AWS_ACCESS_KEY_IDusing domain-protect deploy policy
AWS_SECRET_ACCESS_KEY-
TERRAFORM_STATE_BUCKETtfstate48903
TERRAFORM_STATE_KEYdomain-protect
TERRAFORM_STATE_REGIONus-east-1
TF_VAR_org_primary_account012345678901
TF_VAR_security_audit_role_namenot needed if "domain-protect-audit" used
TF_VAR_external_idonly required if External ID is configured
TF_VAR_slack_channels["security-alerts"]
TF_VAR_slack_channels_dev["security-alerts-dev"]
TF_VAR_slack_webhook_urls["https://hooks.slack.com/services/XXX/XXX/XXX"]
  • to validate an updated CircleCI configuration:
docker run -v `pwd`:/whatever circleci/circleci-cli circleci config validate /whatever/.circleci/config.yml

limitations
  • this tool cannot guarantee 100% protection against subdomain takeover
  • it currently only scans Amazon Route53, and only checks a limited number of takeover types
  • vulnerable domains in Google Cloud DNS can be detected by Domain Protect for GCP