Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Canary Access Token

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: Very High (not tolerated)
Rule ID: IAM-055

Ensure one IAM user is created as Canarytokens within your AWS account in order to implement proactive security defense by using threat deception technology. Deception technology automates the creation of security traps (decoys) which are mixed with existing cloud resources to provide an extra layer of protection that can be used to prevent attackers from gaining access to your AWS resources and/or applications. In this case the IT assets used as decoys are IAM access keys, a set of credentials used to sign programmatic requests that you make to AWS API. These API access keys, also known as Canarytokens, are created with special configuration and limited permissions to help you detect when your AWS cloud resources and applications have been breached by having attackers announce themselves.

This rule can help you with the following compliance standards:

  • NIST4

For further details on compliance standards supported by Conformity, see here.

This rule resolution is part of the Conformity Security & Compliance tool for AWS.

Security

Your AWS API access keys represent an attractive target for attackers and malicious users. Knowing that, you can create Canarytokens (i.e. valid access keys with a very limited set of permissions) and leave them as bait on different targets such as web applications, code repositories, EC2 instances, etc. If attackers breach one of these targets, they will find the access keys and attempt to use them. And when such credentials are used by attackers, a notification alert will inform you of their actions so you can use this information to take measures and secure your AWS environment and/or applications.


Audit

Canary access tokens are IAM access key pairs associated with an AWS IAM user account that has no API or console privileges, hence the IAM user account must have the following configuration: one or more access keys, no permissions (managed and/or inline policies) and no console privileges (no user password enabled). To determine if there are any IAM user access keys used as Canarytokens within your AWS account, perform the following actions:

Using AWS Console

01 Sign in to AWS Management Console.

02 Navigate to IAM dashboard at https://console.aws.amazon.com/iam/.

03 In the left navigation panel, choose Users to list the IAM users available in your AWS account.

04 Click on the name (link) of the IAM user that you want to examine.

05 Select Permissions tab from the dashboard bottom panel, expand Permissions policies and Permissions boundary sections and check for any IAM policies attached to the selected user. If there are no policies currently attached, the selected IAM identity does not have any permissions set, therefore the user account permissions configuration is Canarytoken-compliant, otherwise the configuration is not compliant.

06 In the left navigation panel, choose Credential report.

07 On the Credential report page, click Download Report to download the IAM report that lists all your account's users and the status of their various credentials.

08 Open the downloaded file (i.e. status_reports_<report-download-date>.csv) in your CSV file editor and check the following details for the IAM user selected earlier in the process:

  1. If password_enabled attribute is set to FALSE and password_last_used value is set to N/A (not applicable), the AWS Management Console access is not enabled for the selected user, therefore the IAM user account configuration is compliant, otherwise the configuration is not compliant with the rule requirements.
  2. If access_key_1_active and/or access_key_2_active values are set to TRUE, the selected IAM user has one or more access keys attached, therefore the verified user account configuration is Canarytoken-compliant, otherwise the configuration is not compliant.

09 If the user account configuration is not compliant for both step no. 5 and 8 (a and b), the access keys associated with selected AWS IAM user account are not used as Canarytokens.

10 Repeat steps no. 4 – 9 for each Amazon IAM user available in your AWS account. If there are no IAM user accounts with Canarytoken-compliant configurations, Canary access tokens are not currently used within your AWS account.

Using AWS CLI

01 Run list-users command (OSX/Linux/UNIX) using custom query filters to list the names of all IAM users currently available in your AWS account:

aws iam list-users
	--output table
	--query 'Users[*].UserName'

02 The command output should return a table with the requested IAM user identifiers:

---------------
|  ListUsers  |
+-------------+
| Simon       |
| David       |
| ...         |
| cc-dv-admin |
| ec2-manager |
+-------------+

03 Run list-attached-user-policies command (OSX/Linux/UNIX) using the name of the IAM user that you want to examine as identifier parameter and custom filtering to list the names of the managed access policies currently attached to the selected AWS IAM user:

aws iam list-attached-user-policies
	--user-name Simon
	--query 'AttachedPolicies'

04 The command output should return an array that contains the name of the managed policy (or policies) attached to the IAM user, otherwise it should return an empty array. If the command output returns an empty array, as shown in the example above, there are no managed policies attached to the selected user, therefore the user account permissions configuration is Canarytoken-compliant, otherwise the configuration is not compliant:

[]

05 Run list-user-policies command (OSX/Linux/UNIX) using the name of the AWS IAM user verified at the previous steps as identifier and custom filtering to list the names of the inline policies attached to the selected IAM user:

aws iam list-user-policies
	--user-name Simon
	--query 'PolicyNames'

06 The command output should return an array that contains the name of the inline policy (or policies) associated with the IAM user, otherwise it should return an empty array. If the command output returns an empty array, i.e. [], there are no inline policies currently associated with the selected user, therefore the user account permissions configuration is Canarytoken-compliant:

[]

07 Run get-credential-report command (OSX/Linux/UNIX) to obtain the IAM credential report for the AWS account that you want to examine. A credential report is a CSV document that lists all users available in your AWS account and the current status of their credentials:

aws iam get-credential-report

08 The command output should return the document in a TEXT/CSV format, encoded with the Base64 encoding scheme, e.g.:

{
    "Content": "abcd1234abcd1234abcd1234 ... abcd1234abcd1234abcd1234=",
    "GeneratedTime": "2019-05-04T20:11:32Z",
    "ReportFormat": "text/csv"
}

09 Decode the content of the IAM credential report from the command line (OSX/Linux/UNIX) using the Base64 string returned at the previous step as the input data. In the following example, the report is decoded and saved to a file named iam-users-credentials-report.csv:

echo -n abcd1234abcd1234abcd1234 ... abcd1234abcd1234abcd1234= | base64 –d >> iam-users-credentials-report.csv

10 Open iam-users-credentials-report.csv document in your favorite file editor and check the following details for the IAM user selected earlier in the audit process:

  1. If password_enabled attribute is set to FALSE and password_last_used value is set to N/A (not applicable), the AWS Management Console access is not enabled for the selected user, therefore the IAM user account configuration is compliant, otherwise the configuration is not compliant with the rule requirements.
  2. If access_key_1_active and/or access_key_2_active values are set to TRUE, the selected IAM user has one or more access keys attached, therefore the verified user account configuration is Canarytoken-compliant, otherwise the configuration is not compliant.

11 If the user account configuration is not compliant for step no. 4, 6 and 10 (a and b), the access keys associated with selected AWS IAM user account are not used as Canarytokens.

12 Repeat steps no. 3 – 10 for each Amazon IAM user available in your AWS account. If there are no IAM user accounts with compliant configurations, Canary access tokens are not currently used within your AWS account.

Remediation / Resolution

To configure and use a set of IAM access keys as Canarytokens in your AWS account, you have to create a new IAM user account with no privileges and no access to the AWS Management Console, and generate AWS API access keys for that user. Once the IAM user account is configured, use Amazon CloudWatch and Amazon CloudTrail to build a notification system that will send you alerts whenever someone attempts to use those access keys for any AWS API actions. To create the IAM user account and the notification system required, perform the following actions:

Using AWS Console

01 Sign in to AWS Management Console.

02 Navigate to IAM dashboard at https://console.aws.amazon.com/iam/.

03 In the left navigation panel, choose Users.

04 On the Users page, click Add user button set up the new IAM user account.

05 On the Set user details page, provide a name for your new IAM user in the User name box, then select Programmatic access checkbox under Select AWS access type to generate an access key ID and a secret access key, a key pair that will be used later as decoy to implement threat deception.

06 Click Next: Permissions to continue.

07 On the Set permissions page, just click Next: Tags to continue the setup process.

08 (Optional) On the Add tags (optional) page, use the Key and Value forms to add tag sets to your new IAM user, then click Next: Review to continue.

09 On the Review page, review the access and permissions configuration for your new IAM user account, then click Create user to create the new IAM user.

10 On the confirmation page, click Download.csv button to download the CSV document with the credentials required for Canarytoken, i.e. the access key ID and the secret access key. Click Close to return to the IAM service dashboard.

11 Navigate to CloudTrail dashboard at https://console.aws.amazon.com/cloudtrail/.

12 In the left navigation panel, select Trails.

13 Under Trails, click Create trail to initiate the setup process.

14 On the Create trail page, perform the following:

  1. Provide a name for the new trail in the Trail name box.
  2. Within Storage location section, select Yes next to Create a new S3 bucket and type the name of the new bucket in the S3 bucket box to create a new bucket for log files storage or select No next to Create a new S3 bucket and choose an existing bucket from the S3 bucket box.
  3. Leave the rest of the configuration settings as default, then click Create to create your new trail.

15 Click on the newly created CloudTrail trail to access its configuration page.

16 In the CloudWatch Logs section, click Configure, provide a name for a new or existing CloudWatch log group in the New or existing log group box and click Continue.

17 Click View Details to review the required IAM role details, then click Allow to create the IAM role required to deliver CloudTrail events to your Amazon CloudWatch Logs. Once the permissions are configured, the AWS CloudWatch log group is created.

18 Navigate to CloudWatch dashboard at https://console.aws.amazon.com/cloudwatch/.

19 In the left navigation panel, click Logs.

20 Select the newly created AWS CloudWatch log group and click Create Metric Filter button from the dashboard top menu to start the metric filter setup process.

21 On Define Logs Metric Filter page, in the Filter Pattern box, enter the following pattern: { $.userIdentity.accessKeyId = "AAAABBBBCCCCDDDDEEEE" }, where "AAAABBBBCCCCDDDDEEEE" represents the access key ID generated for your IAM user account and downloaded at step no. 10.

22 Click Assign Metric to continue the process.

23 On Create Metric Filter and Assign a Metric page, provide a name for the selected filter in the Filter Name box and a unique name for the assigned metric within the Metric Name box. Click Create Filter to generate the new metric filter that matches the API access key used as Canarytoken and attach the metric to the AWS CloudWatch log group assigned to your new CloudTrail trail.

24 Navigate to SNS dashboard at https://console.aws.amazon.com/sns/.

25 In the navigation panel, select Topics and click the Create new topic button.

26 In the Create new topic dialog box, enter a name and a display name for your new SNS topic then click Create Topic.

27 Open the newly created SNS topic configuration page by clicking on its Amazon Resource Name (ARN) link.

28 Under Subscription section click Create Subscription.

29 Select Email as subscription protocol from the Protocol dropdown list.

30 In the Endpoint box, enter the email address where you want to receive the AWS CloudWatch alarm notifications when an attacker tries to use the API access key used as decoy, then click Create Subscription to create the required subscription.

31 Use your preferred email client application to open the message received from AWS Notifications, then click on the appropriate link to confirm your new email subscription.

32 Go back to Amazon CloudWatch dashboard at https://console.aws.amazon.com/cloudwatch/.

33 In the left navigation panel, click Logs.

34 Select the Logs CloudWatch log group associated with your new CloudTrail trail and click on the <number> filter link, available in the Metric Filters column, to access the metric filter created for the selected log group.

35 On Filters for <trail-log-group-name> page, choose the metric filter created earlier in the process, then click Create Alarm link available inside the metric box to initiate the AWS CloudWatch alarm setup process.

36 Within Create new alarm dialog box, provide the following information:

  1. Inside the Alarm details section, in the Name and Description boxes, provide a unique name and a short description for your new CloudWatch alarm.
  2. Under Whenever: <metric-name>, select >= (greater than or equal to) from the is dropdown list and enter 1 as the threshold value in the box next to the dropdown list to trigger the alarm every time an attacker attempts to use the specified Canarytoken.
  3. In the Actions section, click the + Notification button, select State is ALARM from the Whenever this alarm dropdown menu and choose the AWS SNS topic name created earlier from Send notification to dropdown list.
  4. Review the alarm configuration details then click Create Alarm. Once created, the new CloudWatch alarm will be listed on the Alarms page. After the monitoring data is loaded, the State (status) of the new Amazon CloudWatch alarm will change from INSUFFICIENT_DATA to OK.

37 Now that the required notification system is created, place the API access keys downloaded at step no. 10 (i.e. the Canarytoken) in locations that an attacker is likely to look in case of a security breach, e.g. web applications, code repositories, EC2 instances.

38 If required, change the AWS region from the navigation bar and repeat the entire process for the other regions.

Using AWS CLI

01 Run create-user command (OSX/Linux/UNIX) to create the required AWS IAM user account:

aws iam create-user
	--user-name Jeff

02 The command output should return the new IAM user metadata:

{
    "User": {
        "UserName": "Jeff",
        "Path": "/",
        "CreateDate": "2019-01-08T17:39:20Z",
        "UserId": "AABBCCDDAABBCCDDAABBC",
        "Arn": "arn:aws:iam::123456789012:user/Jeff"
    }
}

03 Run create-access-key command (OSX/Linux/UNIX) to generate and attach an access key pair to the newly created AWS IAM user. The key pair will be used later as decoy to implement threat deception:

aws iam create-access-key
	--user-name Jeff

04 The command output should return the new IAM user access key ID and a secret access key (including other metadata)

{
    "AccessKey": {
        "UserName": "Jeff",
        "Status": "Active",
        "CreateDate": "2019-01-08T17:41:15Z",
        "SecretAccessKey": "abcd1234abcd1234abcd1234abcd1234abcd1234",
        "AccessKeyId": "AAAABBBBCCCCDDDDEEEE"
    }
}

05 Run create-subscription command (OSX/Linux/UNIX) to create the Amazon CloudTrail trail that will record the necessary AWS API events and save them to log files within an S3 bucket:

aws cloudtrail create-subscription
	--region us-east-1
	--name cc-canary-auth-trail
	--s3-new-bucket cc-canary-auth-logs

06 If successful, the command output should return the new CloudTrail trail metadata:

{
Setting up new S3 bucket cc-canary-auth-logs...
Creating/updating CloudTrail configuration...
CloudTrail configuration:
{
  "trailList": [
    {
      "IncludeGlobalServiceEvents": true,
      "Name": "cc-canary-auth-trail",
      "TrailARN": "arn:aws:cloudtrail:us-east-1:123456789012:trail/cc-canary-auth-trail",
      "LogFileValidationEnabled": false,
      "IsMultiRegionTrail": false,
      "HasCustomEventSelectors": false,
      "S3BucketName": "cc-canary-auth-logs",
      "HomeRegion": "us-east-1"
    }
  ],
  "ResponseMetadata": {
    "RetryAttempts": 0,
    "HTTPStatusCode": 200,
    "RequestId": "abcdabcd-1234-1234-1234-abcdabcdabcd",
    "HTTPHeaders": {
      "x-amzn-requestid": "abcdabcd-1234-1234-1234-abcdabcdabcd",
      "date": "Mon, 08 Apr 2019 18:02:35 GMT",
      "content-length": "345",
      "content-type": "application/x-amz-json-1.1"
    }
  }
}
Starting CloudTrail service...
Logs will be delivered to cc-canary-auth-logs:}

07 Run create-log-group command (OSX/Linux/UNIX) to create the AWS CloudWatch log group required to receive API events from Amazon CloudTrail for monitoring (the command does not produce an output):

aws logs create-log-group
	--region us-east-1
	--log-group-name CloudTrail/CanaryAuthLogGroup

08 Run describe-log-groups command (OSX/Linux/UNIX) to obtain the Amazon Resource Name (ARN) of the CloudWatch log group created at the previous step:

aws logs describe-log-groups
	--region us-east-1
	--log-group-name-prefix CloudTrail/CanaryAuthLogGroup
	--query 'logGroups[*].arn'

09 The command output should return the requested resource ARN:

{
    "arn:aws:logs:us-east-1:122330079136:log-group:CloudTrail/CanaryAuthLogGroup:*"
]

10 Create the policy for the IAM role that AWS CloudWatch needs to assume, and paste the following content to a file named assume-role-policy.json:

{
  "Version": "2012-10-17",
  "Statement": [
    {

      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

11 Run create-role command (OSX/Linux/UNIX) to create the IAM role that enables CloudTrail to send events to the new AWS CloudWatch log group:

aws iam create-role
	--role-name CloudTrail_CloudWatchLogs_Role
	--assume-role-policy-document file://assume-role-policy.json

12 Create the IAM role access policy that will grant Amazon CloudTrail the required permissions to create CloudWatch log streams in the log group created earlier in the process. Replace the highlighted values with your own configuration data and save the policy to a file named cloudtrail-cloudwatch-role-policy.json:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailCreateLogStream",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:123456789012:log-group:CloudTrail/DefaultLogGroup:log-stream:123456789012_CloudTrail_us-east-1*"
            ]
        },
        {
            "Sid": "AWSCloudTrailPutLogEvents",
            "Effect": "Allow",
            "Action": [
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:us-east-1:123456789012:log-group:CloudTrail/DefaultLogGroup:log-stream:123456789012_CloudTrail_us-east-1*"
            ]
        }
    ]
}

13 Run put-role-policy command (OSX/Linux/UNIX) to apply the policy defined at the previous step, i.e. cloudtrail-cloudwatch-role-policy.json, to the required AWS IAM role:

aws iam put-role-policy
	--role-name CloudTrail_CloudWatchLogs_Role
	--policy-name cloudtrail-cloudwatch-role-policy
	--policy-document file://cloudtrail-cloudwatch-role-policy.json

14 Run update-trail command (OSX/Linux/UNIX) to update your CloudTrail trail configuration with the AWS CloudWatch log group and IAM role information. Replace the specified log group and role ARNs with your own ARNs:

aws cloudtrail update-trail
	--region us-east-1
	--name cc-canary-auth-trail
	--cloud-watch-logs-log-group-arn arn:aws:logs:us-east-1:123456789012:log-group:CloudTrail/CanaryAuthLogGroup:*
	--cloud-watch-logs-role-arn arn:aws:iam::123456789012:role/CloudTrail_CloudWatchLogs_Role

15 The command output should return the new AWS CloudTrail trail configuration:

{
    "IncludeGlobalServiceEvents": true,
    "Name": "cc-canary-auth-trail",
    "TrailARN": "arn:aws:cloudtrail:us-east-1:123456789012:trail/cc-canary-auth-trail",
    "LogFileValidationEnabled": false,
    "S3BucketName": "cc-canary-auth-logs",
    "CloudWatchLogsRoleArn": "arn:aws:iam::123456789012:role/CloudTrail_CloudWatchLogs_Role",
    "CloudWatchLogsLogGroupArn": "arn:aws:logs:us-east-1:123456789012:log-group:CloudTrail/CanaryAuthLogGroup:*"
}

16 Run put-metric-filter command (OSX/Linux/UNIX) to create the required metric filter and associate it with the specified CloudWatch log group. This metric implements a Filter Pattern that matches the access key ID created at step no. 3 (i.e. the Canarytoken). Replace "AAAABBBBCCCCDDDDEEEE" with your own access key ID (the command does not produce an output):

aws logs put-metric-filter
	--region us-east-1
	--log-group-name CloudTrail/CanaryAuthLogGroup
	--filter-name cc-canary-log-filter
	--filter-pattern "{ $.userIdentity.accessKeyId = \"AAAABBBBCCCCDDDDEEEE\" }"
	--metric-transformations metricName=cc-canary-log-metric,metricNamespace=LogMetrics,metricValue=1

17 The command output should return the ARN for the newly created AWS SNS topic:

{
   "TopicArn": "arn:aws:sns:us-east-1:12345678901:cc-vpc-flow-log-notifications "
}

18 To set up the notification system, run create-topic command (OSX/Linux/UNIX) to create a new SNS topic for sending email notifications whenever the required AWS CloudWatch alarm is triggered:

aws sns create-topic
	--name cc-canary-auth-notifications

19 The command output should return the ARN for the newly created AWS SNS topic:

{
    "TopicArn": "arn:aws:sns:us-east-1:123456789012:cc-canary-auth-notifications"
}

20 Run subscribe command (OSX/Linux/UNIX) to send the subscription confirmation message to the notification endpoint (the email address provided as endpoint):

aws sns subscribe
	--region us-east-1
	--topic-arn arn:aws:sns:us-east-1:123456789012:cc-canary-auth-notifications
	--protocol email
	--notification-endpoint notifyme@cloudconformity.com

21 The command output should return the following:

{
    "SubscriptionArn": "pending confirmation"
}

22 Run confirm-subscription command (OSX/Linux/UNIX) to confirm the email subscription by validating the token sent to the notification endpoint selected:

aws sns confirm-subscription
	--topic-arn arn:aws:sns:us-east-1:123456789012:cc-canary-auth-notifications
	--token de76e15f37fb687f5d51e6e241d7700ae02f7124d8268910b858cb4db727cesb2474bb937929d3bdd7ce5d0cce19325d036bc498d3c217426bcafa9c501a2cace93b83f1dd3797627467553dc438a8c974119496fc3eff026eaa5d14472ded6f9a5c43aec62d83ef5f49109da71efb7gx78

23 The command output should return the confirmed subscription ARN:

{
    "SubscriptionArn": "arn:aws:sns:us-west-2:123456789012:cc-canary-auth-notifications:abcdabcd-1234-1234-1234-abcd1234abcd"
}

24 Run put-metric-alarm command (OSX/Linux/UNIX) to create the Amazon CloudWatch alarm that fires whenever someone attempts to use the access keys pair defined as Canarytoken (if successful, the command does not return an output):

aws cloudwatch put-metric-alarm
	--region us-east-1
	--alarm-name cc-canary-auth-alarm
	--alarm-description "Triggered by Canarytoken usage."
	--metric-name cc-canary-log-metric
	--namespace LogMetrics
	--statistic Sum
	--comparison-operator GreaterThanOrEqualToThreshold
	--evaluation-periods 1
	--period 300
	--threshold 1
	--actions-enabled
	--alarm-actions arn:aws:sns:us-east-1:123456789012:cc-canary-auth-notifications

25 Now that the required notification system is created, place the API access keys created at step no. 3 as Canarytoken in locations that an attacker is likely to look in case of a security breach, e.g. web applications, code repositories, EC2 instances.

26 If required, change the AWS region by updating the --region command parameter value and repeat the entire remediation process for other regions.

References

Publication date Apr 10, 2019