l01cd3v.github.io

by Loïc


Work daily with enforced MFA-protected API access

Published on April 3, 2015
[Originally published on iSEC Partners's research blog]

AWS Security Token Service

The AWS Security Token Service (STS) is the gateway used to create sessions when MFA-protected API access is enabled. This service allows IAM users to retrieve short-lived credentials (i.e access key ID, secret access key, and session token) in exchange for their long-lived credentials (i.e. AWS access key ID and secret key) and their current authentication code. When enforcing MFA-protected API access, as recommended in the previous Use and enforce Multi-Factor Authentication post, IAM users must use these short-lived credentials to access other AWS services.

Challenges with MFA-protected API access

When MFA-protected API access is enforced, managing AWS access keys becomes challenging because configuration files that contain these credentials must be updated regularly. Users must also ensure that they do not lose their long-lived credentials when modifying the configuration files to write their short-lived credentials. In order to help with this workflow, iSEC wrote and released several simple tools in the AWS-recipes repository.

The collection of tools that we will discussed below uses the "new and standardized way to manage credentials in the AWS SDKs", meaning that SDKs are expecting to read credentials from the .aws/credentials file under the user's home or profile directory.

aws_recipes_configure_iam.py

The aws_recipes_configure_iam.py tool allows users to configure and store their long-lived credentials in a new, non-standard, .aws/credentials.no-mfa file. In addition to prompting for the AWS access key ID and secret key, this tool also prompts for the MFA device serial number because this information must be provided when making calls to the STS API. Similar to the AWS CLI and SDKs, it supports profile names. The following code snippet is an example of calling this tool to configure a new profile called isecpartners:

$ ./aws_recipes_configure_iam.py --profile isecpartners
AWS Access Key ID: AWS_KEY_ID
AWS Secret Access Key: AWS_SECRET_KEY
AWS MFA serial: arn:aws:iam::AWS_ACCOUNT_ID:mfa/USER_NAME

When looking at the .aws folder, we can see that a credentials.no-mfa file exists and that it contains the credentials that were just entered:

$ ls -l ~/.aws
total 4
-rw-r--r-- 1 loic loic 93 Apr  3 14:00 credentials.no-mfa
$ cat ~/.aws/credentials.no-mfa
[isecpartners]
aws_access_key_id = AWS_KEY_ID
aws_secret_access_key = AWS_SECRET_KEY
aws_mfa_serial = arn:aws:iam::AWS_ACCOUNT_ID:mfa/USER_NAME

Now that long-lived credentials are configured, we can use the next tool to call the AWS STS API and request short-lived credentials that will be used to access other AWS services.

aws_recipes_init_sts_session.py

The aws_recipes_init_sts_session.py tool reads long-lived credentials configured in the .aws/credentials.no-mfa file, prompts users for their MFA code, and retrieves STS credentials (AWS access key ID, AWS secret key, and session token). The short-lived credentials are then saved under the standardized .aws/credentials file to be accessible to the AWS CLI and other tools built with the AWS SDKs. The following code snippet demonstrates calling this tool to request an STS session token:

$ ./aws_recipes_init_sts_session.py --profile isecpartners
Enter your MFA code: 123456
Successfully configured the session token for profile 'isecpartners'.

When looking at the .aws folder, we can see that a standard credentials file now exists as well and that it contains the short-lived credentials:

$ ls -l ~/.aws
total 8
-rw-r--r-- 1 loic loic 576 Apr  3 14:14 credentials
-rw-r--r-- 1 loic loic 179 Apr  3 14:00 credentials.no-mfa
$ cat ~/.aws/credentials
[isecpartners]
aws_access_key_id = STS_KEY_ID
aws_secret_access_key = STS_SECRET_KEY
aws_mfa_serial = arn:aws:iam::AWS_ACCOUNT_ID:mfa/USER_NAME
aws_session_token = AWS//////////SESSION_TOKEN

Now that the short-lived credentials are configured, we can use the AWS CLI or other tools built with the AWS SDKs that read credentials from this standard location. When the STS session expires, users just need to re-run the aws_recipes_init_sts_session.py tool and the standard credentials file will be updated with new valid short-lived credentials.

Conclusion

By using this pair of tools to manage their AWS access keys, IAM users can easily use the AWS CLI and other tools built with various AWS SDKs in environments that have been secured and enforce MFA-protected API access.


Use and enforce Multi-Factor Authentication

Published on April 2, 2015
[Originally published on iSEC Partners's research blog]

What is Multi-Factor Authentication?

When enabled, Multi-Factor Authentication (MFA) provides strong defense-in-depth against compromises of credentials. MFA-enabled users have a device that periodically generates a new authentication code (i.e. one-time password); they need to enter the current authentication code along with their static credentials (i.e. username and password) in order to successfully authenticate. In addition to supporting MFA when accessing the web console (i.e. password-based authentication), AWS also offers MFA-protected API access for users who work with AWS access keys. Through the Security Token Service (STS), IAM users can request temporary credentials in exchange for their long-lived credentials (i.e. AWS access key ID and secret key) and their current authentication code.

Why should one use and enforce MFA?

For companies deploying their application in the cloud, a breach that results in unauthorized access to the management console — or API — is the worst-case scenario. While a number of AWS administrators have realized the importance of enabling MFA when they access the web console, a limited number of them enforce MFA-protected API access. This represents a huge gap in one's security posture because AWS access keys do not come with as many security features as passwords do:

  • AWS administrators can enforce password expiration; this is currently not possible for AWS access keys.
  • While it is probably safe to assume that most AWS administrators do not store their password in plaintext, most of them use AWS access keys. By design, these keys are meant to be stored in plaintext files that are accessed by tools built with the various AWS SDKs.
  • A lost password is a forgotten password; a lost key is a key stored in a lost file, which may be on an unencrypted storage device (e.g. hard drive or USB Flash drive).

Because AWS access keys are long-lived credentials that are stored in plaintext files, they are more susceptible to compromise than passwords. It is therefore necessary to enable MFA when the AWS API is accessed using these keys and not only when users sign in using their passwords.

How can one enforce MFA?

Unfortunately, at time of writing, AWS does not offer an option to enforce MFA-protected API access via a global setting. Therefore, AWS account administrators must carefully manage their IAM users and develop a strategy to reliably achieve this. In order to enforce MFA-protected API access, iSEC recommends the following:

  1. Create a common IAM group that all IAM users belong to, as discussed in the previous IAM user management strategy post.
  2. Add the following policy (also available on Github) to enforce MFA for all users who belong to this group.

This policy will enforce MFA regardless of how the IAM user authenticated with AWS; it will be effective whether they use password-based or key-based authentication.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "Null":{"aws:MultiFactorAuthAge":"true"}
      }
    },
    {
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "NumericGreaterThan":{"aws:MultiFactorAuthAge":"28800"}
      }
    }
  ]
}

The first statement in the above policy denies all actions if the aws:MultiFactorAuthAge key is not present; this key only exists if MFA is used [1].

The second statement verifies that the validation of the MFA code was performed less than eight hours ago. Temporary credentials may be valid for a duration between fifteen minutes and thirty-six hours [2]. iSEC recommends requiring users to initiate a new session at least once a day.

Note: An "explicit deny" means that, regardless of other policies granted to a user, this deny rule will prevail. More information about the IAM policy evaluation logic can be found in the AWS documentation at http://docs.aws.amazon.com/IAM/latest/UserGuide/AccessPolicyLanguage_EvaluationLogic.html.

Use AWS Scout2 to detect users without MFA

The default ruleset used by AWS Scout2 includes a rule that checks for IAM users who have password-based authentication enabled but do not have an MFA device configured. If Scout2 detects IAM users with password-based authentication enabled and no MFA device, it will document a "Lack of MFA" security risk in the IAM menu dropdown, as illustrated in the below screenshot.

Screenshot: IAM menu dropdown with a "Lack of MFA" security risk

When clicked, this "Lack of MFA" link filters the list of IAM users to display those who have password-based authentication enabled but no MFA device configured. The red "No" following "Multi-Factor enabled" indicates a danger tied to that particular IAM user.

Screenshot: Red "No" indicating that this IAM user may access the web console without MFA

How can one use MFA with command line tools?

Users of the AWS CLI (and other command line tools) have several methods to configure their credentials, such as environment variables, configuration files, or command line arguments. However, updating these settings on a daily basis when MFA-protected API access is enabled is inconvenient. To help facilitate this work flow, iSEC has created a set of Python tools and released them in the AWS-recipes repository. Further details about these tools will be published in the next blog post.

Additional information about MFA with AWS is available in the AWS documentation at https://docs.aws.amazon.com/IAM/latest/UserGuide/Using_ManagingMFA.html.

Conclusion

Enforcing Multi-Factor Authentication for all IAM users is extremely important in order to mitigate the risks of credentials compromise (especially the AWS access key ID and secret). This aspect of security is commonly overlooked and may result in catastrophic damages. By using a strict strategy for management of IAM users and the above IAM policy, AWS administrators may significantly reduce risks of account compromise.

[1] http://docs.aws.amazon.com/IAM/latest/UserGuide/AccessPolicyLanguage_ElementDescriptions.html#AvailableKeys

[2] http://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html


IAM user management strategy

Published on February 24, 2015
[Originally published on iSEC Partners's research blog]

Use IAM groups

When granting privileges to IAM users, AWS account administrators should avoid use of user-specific policies. Instead, create groups whose name explicitly defines the members' job functions or responsibilities (e.g. AWS Administrators, Operations, Developers, Accountants), and define the permissions granted within group policies. Doing so will simplify the permissions management process as changes in group policies apply to all members.

When performing AWS configuration reviews, iSEC often discovers IAM users whose privileges have been granted via a combination of IAM user and IAM group policies. It is not uncommon to see IAM users who are granted full administrator privileges in a redundant manner, via both user and group policies. Such configuration creates an avenue for configuration mistakes, as another administrator may believe that terminating an IAM user's membership to the admin group is sufficient. Therefore, banning use of IAM user policies will result in making one's AWS environment less error-prone.

Note: It is on purpose that iSEC recommends using IAM group names that reflect a job title or responsibility. IAM users who do not fit in such groups (e.g. headless users) should not exist. Instead, AWS account administrators should investigate use of IAM roles for EC2. Further details will be discussed in an upcoming blog post.

Create a common IAM group to apply generic policies

Because a number of policies must be applied to all users, iSEC recommends that AWS account administrators create an IAM group that all IAM users belong to. Doing so will allow AWS account administrators to consistently grant privileges and enforce a number of rules.

Note: It is important that all IAM users belong to this common IAM group to ensure that policies are consistently applied. Failure to do so will create gaps in one's AWS environment security posture.

Authorize IAM users to manage their credentials

To begin with, iSEC recommends that AWS account administrators allow all of their IAM users to manage their credentials, and only theirs. With all IAM users belonging to the common IAM group, this can be achieved by applying the following IAM policy to the group.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
                 "iam:*AccessKey*",
                 "iam:*Password",
                 "iam:*MFADevice*",
                 "iam:UpdateLoginProfile"
        ],
      "Resource": "arn:aws:iam::AWS_ACCOUNT_ID:user/${aws:username}"
    },
    {
      "Effect": "Allow",
      "Action": [
                 "iam:CreateVirtualMFADevice",
                 "iam:DeleteVirtualMFADevice"
      ],
      "Resource": "arn:aws:iam::AWS_ACCOUNT_ID:mfa/${aws:username}"
    }
  ]
}

While the above policy is sufficient to allow users to manage their credentials, AWS administrators may consider the following statement as an addition; it allows IAM users to know what the account's password policy is.

{
  "Effect": "Allow",
  "Action": "iam:GetAccountPasswordPolicy",
  "Resource": "*"
}

Use AWS Scout2 to detect user policies

The default ruleset used by AWS Scout2 includes a rule that checks for user policies and reports the use of user-specific IAM policies as a warning. Detection of user-specific IAM policies results in the IAM menu dropdown containing a "User policies" security risk, as illustrated in the below screenshot.

Screenshot: IAM menu dropdown with a User policies security risk

When clicked-on, this "User policies" link filters the list of IAM users to only display those who have at least one user policy attached. The orange badge indicates a warning and the count of user policies attached to this particular IAM user.

Screenshot: Orange badge indicating that at least one user policy is attached to that IAM user

Check that all IAM users belong to the common group

AWS Scout2 comes with a tool — RulesGenerator.py — that allows AWS account administrators to generate a custom ruleset to tailor the report to their needs. An optional IAM rule requires all IAM users to belong to a common IAM group. In order to enable this rule, the following can be done:

  1. Run the rules generator with the following command line:
    ./RulesGenerator.py --ruleset_name isec --services iam
  2. Answer "yes" to the question "Would you like to ensure that all IAM users belong to a given IAM group?"
  3. Enter the name of your common group (e.g. AllUsers)
  4. Enter "yes" or "y" to confirm
  5. Change the level if desired
  6. Run Scout2

Note: If you have already run Scout2 and do not wish to download the latest IAM configuration, use the following command to run an offline analysis:

./Scout2.py --ruleset_name isec --services iam --local

The following screenshot illustrates the IAM menu dropdown containing a security risk when IAM users do not belong to the configured common group.

Screenshot: IAM menu dropdown when IAM users do not belong to the common group

When clicked-on, this link filters the list of IAM users to only display those who do not belong to the common IAM group. A colored warning sign appears, warning about this issue.

Screenshot: Orange badge indicating that at least one user policy is attached to that IAM user

Conclusion

Strict management of IAM users and tight control of their privileges is key in maintaining a secure AWS environment. When followed, the above recommendations should enable AWS administrators to manage IAM users with improved efficiency and lower the chances of overly privileged users to exist.


Do not use your AWS root account

Published on February 23, 2015
[Originally published on iSEC Partners's research blog]

What is the AWS root account?

The AWS root account is the account that was used -- or created -- when signing up with Amazon Web Services. This account has full access to all resources in the account and it is not possible to alter this configuration.

Risks of using the AWS root account

Using the AWS root account means that there is potential for its compromise. In particular, iSEC noticed that AWS customers who use the AWS root account tend to do the following:

  1. Share credentials between employees.
  2. Disable Multi-Factor Authentication (MFA) for convenience.

Shared credentials, aside from increasing the risk of compromise during the sharing process, render credential rotation impractical due to the need for the newly-generated secret to be known by multiple parties. Sharing the AWS root account also undermines any effort towards using IAM and leveraging the fine-grained access controls it offers. Finally, shared credentials result in loss of the attribution ability, which makes auditing harder and may prevent successful investigation.

AWS Identity and Access Management (IAM)

AWS IAM allows account administrators to create users for every employee and grant them access to a limited set of services, actions, and resources. This allows AWS account administrators to apply the principle of least privilege, which dictates that a given user should only be able to access the information and resources that are necessary for them to perform tasks they are responsible for. Additionally, use of IAM allows AWS users to rotate credentials and revoke privileges without impacting other employees.

AWS account administrators should create an Administrator IAM group, grant administrator privileges to this group, and create individual IAM users for each employee in charge of administrating the AWS account. When done, the AWS root password should be rotated and stored in a safe manner. Furthermore, additional credentials such as access keys and certificates should be deleted.

Important security consideration about the root account

AWS users should always enable MFA on their root account, even when the password is securely stored; it is important to realize that the password reset for the root account process only requires access to the email address associated with this account. This means that, without MFA, your production environment is only as secure as an email.


Announcing the AWS blog post series

Published on February 22, 2015
[Originally published on iSEC Partners's research blog]

Starting this month, iSEC Partners will start a series of blog posts related to AWS. The goal of these blog posts will be to:

  • Discuss common security gaps in AWS environments
  • Discuss common security gaps in the architecture of applications deployed in the cloud
  • Describe methods and tools used to identify these security gaps
  • Share tools and scripts that facilitate daily and secure work with AWS
  • Share AWS policies that help improve the security posture of AWS environments

To share material, iSEC created a new public AWS-recipes repository on Github. The tools and policies shared in this repository will be discussed and explained in dedicated blog articles.

Because iSEC has been assessing the security of AWS environment for several years, we have a number of ideas and articles in the pipe awaiting to be written and published. Our target goal is to publish at least on a bi-monthly basis at the beginning of the project, and adjust this publication rate after we catch up.

Without further due, we will start this series with articles that discuss Identity and Access Management (IAM) common issues and best practices, and will present a strategy to improve one's security posture when using AWS.