Skip to main content
Introduction

Multi-Factor Authentication (MFA) is an effective security control which decreases the likelihood of attackers being able to successfully use compromised credentials to gain access to an account. In general, it helps to mitigate the impact of a successful password-brute force attack or credentials being inadvertently disclosed to an attacker, such as through a phishing campaign or if credentials are leaked in some other way, such as storing them on a public GitHub repository, shared file share, or shared workspace (such as a VDI).

Background

Whilst on a recent threat modeling engagement involving an AWS environment, we noticed that the administrators of the account were required to MFA before being allowed to perform the majority of the permissions associated with their account.

The IAM policy used to enforce MFA is commonly implemented. It is recommended by AWS, and restricts users so that they can only perform a limited set of actions (such as creating a new MFA device and assigning it to their IAM user), whilst all other actions (which they may be assigned via additional IAM policies) are denied until they have successfully carried out MFA.

The full IAM policy, and some additional clarification as to the purpose of including various statements within the policy, can be found at AWS: Self-manage credentials with MFA (My security credentials).

Relevant IAM Policies

The two important parts of the relevant IAM policy, for the purposes of this blog post, are the statements that allow users to create and activate a MFA device:

{
"Sid": "AllowManageOwnUserMFA",
	"Effect": "Allow",
	"Action": [
		"iam:DeactivateMFADevice",
		"iam:EnableMFADevice",
		"iam:ListMFADevices",
		"iam:ResyncMFADevice"
	],
"Resource": "arn:aws:iam::*:user/${aws:username}"
}

And the statements preventing users from performing any actions that they would otherwise have the necessary permissions to perform, unless they have first successfully carried out MFA:

{
"Sid": "DenyAllExceptListedIfNoMFA",
	"Effect": "Deny",
	"NotAction": [
		"iam:CreateVirtualMFADevice",
		"iam:EnableMFADevice",
		"iam:GetUser",
		"iam:ListMFADevices",
		"iam:ListVirtualMFADevices",
		"iam:ResyncMFADevice",
		"sts:GetSessionToken"
	],
	"Resource": "*",
	"Condition": {
		"BoolIfExists": {
			"aws:MultiFactorAuthPresent": "false"
                }
        }
}
Analysis of This Policy

This control is implemented through the use of the NotAction policy element. NotAction effectively creates an array of all possible AWS actions, across all AWS services (besides the specific actions listed in the NotAction array), that will be denied ("Effect":"Deny") unless the user has carried out MFA ("aws:MultiFactorAuthPresent": "false"). Once the user has performed MFA, the condition element of this statement becomes false, and they will no longer be denied access to the other actions which they are allowed to perform.

When first introduced by AWS, this policy worked as intended. An administrator could create a new IAM user and assign it permissions, including the above policy, and give the credentials to the intended user. The user could then authenticate to the AWS account, and would be required to create and assign a MFA device to their IAM user before being allowed to perform the other AWS actions that they required to fulfill their work functions.

If the IAM user’s credentials were compromised, the attacker would not be able to do anything except for the limited actions specified in the above NotAction array, as they would not have access to the MFA device. Furthermore, they could not create and assign a new MFA device to bypass the MFA requirement as they would need to first deactivate the user’s existing MFA device (using the “iam:DeactivateMFADevice" action) before they could assign a new MFA device, and this action did not form part of the NotAction array — and therefore could not be performed without first carrying out MFA.

Why the Control Failed

In Novemeber 2022, AWS implemented a change that allowed IAM users to assign 8 independent MFA devices to their account, as detailed in AWS’s blog post You can now assign multiple MFA devices in IAM. However, this change partially invalidated the protections that MFA provided to IAM users that had been assigned the recommended IAM MFA policy.

After this change, an attacker who had compromised an IAM user’s long-term credentials (i.e. AWS access keys beginning with the string AKIA) no longer needed to deactivate the current MFA device before assigning a new MFA device to the user. The attacker could thus use the AWS CLI to create and assign a new MFA device, in their control, to the IAM user and then use it to MFA to gain access to all the other permissions assigned to the IAM user. This is possible since, as described earlier, creating a new MFA device is permitted by the DenyAllExceptListedIfNoMFA policy statement without requiring MFA first. Thus, after the November 2022 change, any IAM users that had the AWS: Self-manage credentials with MFA IAM policy attached to them actually did not have the protections of MFA enabled for long-term credentials associated with their account, and MFA has now become SFA for them. It should be noted that this attack did not work when using the AWS web console, since the console enforces the use of an existing MFA at login, and so the attacker will not be able to add a new MFA device without access to the old device.

Conclusion

By abusing the November 2022 change, an attacker would be able to circumvent the MFA protections applied to AWS long-term access keys for an IAM user protected by the above policy. Furthermore, an attacker whom is able to perform the iam:CreateAccessKey action for another IAM user would also be able to circumvent the above protections for a victim account.

It should be noted that organisations using SSO which enforces MFA, either via an external IdP or AWS SSO, were not affected. Furthermore, this issue only affected AWS CLI long-term credentials as the AWS web console login requires that the IAM user authenticates using an MFA device — which would prevent an attacker from being able to add an additional MFA device if they compromised the console credentials for an IAM user.

MWR CyberSec reached out to AWS after confirming that the above attack is possible. As of the 21st of April 2023, AWS implemented a fix requiring the use of an existing MFA device before permitting the enablement of a new device, effectively remediating the issue. We have co-ordinated the disclosure of this finding with AWS, and their Security Bulletin can be found at Issue With IAM Supporting Multiple MFA Devices.

Disclosure Timeline

19 January 2023 – We reached out to AWS regarding this finding. They immediately responded and kept us informed whilst implementing a fix.

21 April 2023 – AWS implemented a change related to Multi-Factor Authentication enablement for IAM users. Specifically, IAM principals that already have an MFA device configured must now authenticate their session with MFA in order to access the EnableMFADevice API when acting on themselves.

25 April 2023 – MWR CyberSec confirmed that this bypass has been effectively remediated. When trying to enable a device for a user via the CLI, without having first successfully performed MFA, the following error message is returned:

An error occurred (AccessDenied) when calling the EnableMFADevice operation: To complete this action, please ensure that you are authenticated with an MFA device that is enabled for this user.