Is there any way to check the value of aws:MultiFactorAuthPresent - amazon-web-services

I have a policy that denies operations except if aws global context key aws:MultiFactorAuthPresent is true. Meaning that the operation requires that you are authenticated via MFA.
The policy is working ok, and I can see that when I use my aws profile without mfa the operations are denied and when I use the profile with MFA they work.
Now, is there any command / api operation that tells me if my credentials used MFA (aws:MultiFactorAuthPresent)?
I need it for troubleshooting purpose mainly when other people complain that they are getting Operation Denied? Something like aws sts get-caller-identity but that also print out if the credentials used an MFA code.

If I understand correctly, you would want to check if certain users did authenticate themselves with MFA before doing some operations in your account.
I'm not aware of any kind of CLI command for this. What would be helpful for you is to take a look a the CloudTrail Event History. This should log all the operations done by other users. If you download this list of events as a JSON, you should be able find a section with sessionContext for every event.
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "...",
"arn": "...",
"accountId": "...",
"userName": "..."
},
"webIdFederationData": {},
"attributes": {
"creationDate": "2022-02-18T14:08:57Z",
"mfaAuthenticated": "false"
}
}
We can notice that every it is logged that session used by the user/role is MFA authenticated or not.
If you are willing to search for operations done by certain users, you should be able to detect if they were using MFA or not. Just as warning, this JSON file can be huge and could be really painful to go through it.

If you simply want to make sure that users are using MFA when working with AWS CLI you can also enforce MFA usage with aws sts get-session-token (see also https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/get-session-token.html). Therefore users start creating a temporary session with explicit MFA usage (see parameter --serial-numer and --token-code). All commands execute with these temporary session credentials are MFA enforced.

Related

How to delete / deactivate a rogue MFA device in AWS?

I introduced a policy that requires the users in a group to enable MFA. After enabling the policy I logged into an user account (user-foo) to try it out and apparently created a kind of a rogue MFA device when I aborted the setup of a virtual MFA device.
This led to the following error when the user tried to connect his MFA device:
Here is a list of the MFA devices. For comparison I added the output of user-bar with a correctly initialized MFA device.
$ aws iam list-virtual-mfa-devices
{
"VirtualMFADevices": [
{
"SerialNumber": "arn:aws:iam::123456789010:mfa/user-foo"
},
{
"SerialNumber": "arn:aws:iam::123456789010:mfa/user-bar",
"User": {
"Path": "/",
"UserName": "user-bar",
"UserId": "ABCDEFGHIJKLMNOPQRSTU",
"Arn": "arn:aws:iam::123456789010:user/user-bar",
"CreateDate": "2020-07-02T09:45:21Z",
"PasswordLastUsed": "2020-07-03T08:56:47Z"
},
"EnableDate": "2020-07-02T11:07:07Z"
}
]
}
As you can see, only the serial number for the MFA device of user-foo shows up. To delete the entry on the CLI also the user name is required. So I logged in as admin and assigned my phone as MFA device. Now the device showed up properly, but after deleting it with:
$ deactivate-mfa-device --user-name user-foo --serial-number arn:aws:iam::123456789010:mfa/user-foo
It appears again with its serial number without the user:
$ aws iam list-virtual-mfa-devices
{
"VirtualMFADevices": [
{
"SerialNumber": "arn:aws:iam::123456789010:mfa/user-foo"
},
[...]
]
}
Does anyone have an idea how to fix this?
Okay, pretty easy solution: It works if the MFA device is deleted in the console. For some reason this is not possible from the command line.
When you start the process and end it it creates that error and creates a disabled unassigned MFA device. Even though it has the user name in the arn, it is still assigned. It is possible to delete the MFA device from the command line.
aws iam delete-virtual-mfa-device --serial-number arn:aws:iam::123456789010:mfa/user-foo
If the device were enabled you would have to disable it prior to being able to delete it. The completion of setting up an MFA device needs to be done in one pass or will create this error.

Identify AWS IAM user that assumed an IAM role

I'm working on a system that receives new findings from Amazon GuardDuty. Most access in our organization is delegated to IAM roles instead of directly to users, so the findings usually result from the actions of assumed roles, and the actor identity of the GuardDuty finding looks something like this:
"resource": {
"accessKeyDetails": {
"accessKeyId": "ASIALXUWSRBXSAQZECAY",
"principalId": "AROACDRML13PHK3X7J1UL:129545928468",
"userName": "my-permitted-role",
"userType": "AssumedRole"
},
"resourceType": "AccessKey"
},
I know that the accessKeyId is created when a security principal performs the iam:AssumeRole action. But I can't tell who assumed the role in the first place! If it was an IAM user, I want to know the username. Is there a way to programmatically map temporary AWS STS keys (starts with ASIA...) back to an original user?
Ideally I'm looking for a method that runs in less than 30 seconds so I can use it as part of my security event pipeline to enrich GuardDuty findings with the missing information.
I've already looked at aws-cli and found aws cloudtrail lookup-events but it lacks the ability to narrow the query to a specific accessKeyId so it takes a loooong time to run. I've explored the CloudTrail console but it's only about as capable as aws-cli here. I tried saving my CloudTrail logs to S3 and running an Athena query, but that was pretty slow too.
This seems like it would be a common requirement. Is there something obvious that I'm missing?
Actually, aws-cli can perform a lookup on the session! Just make sure to specify ResourceName as the attribute key in the lookup attributes.
$ aws cloudtrail lookup-events \
--lookup-attributes 'AttributeKey=ResourceName,AttributeValue=ASIALXUWSRBXSAQZECAY' \
--query 'Events[*].Username'
[
"the.user#example.com"
]

AWS Access keys without accessing the console

Is it possible to get AWS access keys without generating one from the console?
I want to be able to create a script that will ask for user/password/(TOTP) and generate temporary access keys in order to perform multiple tasks.
The goal being to be able to give one program to dev so they don't even have to deal with access keys every time since they know their password.
I looked everywhere I believe, but cannot find any resources on if it is even doable.
Thank you!
Yes it is doable.
Both via Command Line Interface (CLI) and API are possible.
The CLI command is:
aws iam create-access-key
The API call is:
CreateAccessKey
See documentation reference below for more information. It is a good read and covers best practice topics like rotating your keys with API or CLI. Another good best practice is NOT using your root account for everyday use.
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey_CLIAPI
UPDATE KEY ROTATION EXAMPLE USING CLI:
Before you try this from the CLI - create a new IAM user with Administrator privileges.
Step 1 - configure the CLI to use the Administrator keys:
aws configure
then enter the Access Key ID and Secret Access Key for Administrator.
Step 2 - list the keys for user foo
aws iam list-access-keys --user-name foo
The output will be similar to:
{
"AccessKeyMetadata": [
{
"UserName": "foo",
"AccessKeyId": "AKIAIY*****A7YBHCBEBQ",
"Status": "Active",
"CreateDate": "2018-11-10T14:02:56Z"
}
]
}
Verify there is only one, because a user can have maximum of 2. If they have 2 already, then step 3 will fail.
Step 3 - create a new key for user foo
aws iam create-access-key --user-name foo
you will see output similar to below. This is the only time you will see the secret key for the new set, so you need to preserve it.
{
"AccessKey": {
"UserName": "foo",
"AccessKeyId": "****GAGA*****WEFWEWE",
"Status": "Active",
"SecretAccessKey": "*****sEcReT*****Tasdasd",
"CreateDate": "2018-12-01T19:16:41Z"
}
}
You new key is created and active. Now you need to remove the older key to complete the rotation. I will leave that step up to you.
If you get the error:
An error occurred (InvalidClientTokenId) when calling the ListAccessKeys operation: The security token included in the request is invalid.
then this is a sign you are trying this from an account that your token is old, invalid, or doesnt have the correct privileges.

How can I determine which role I've received after logging into AWS Cognito via JavaScript?

After I log in to AWS Cognito via my browser, I get an access key and a secret access key along w/a session token, but I can't see which role I've been assigned. I know which role I should be assigned, but is there a way to programmatically validate this?
I'm trying to use the role I've been assigned to access a restricted bucket, but am so far not having any success and one of the ways for me to trouble shoot this is to determine which role I've been assigned.
With sts.GetCallerIdentity.
cli example (js link above):
aws --profile XXXXXXXX sts get-caller-identity
{
"UserId": "AIDAIXXXXXXXXTHOVLM",
"Account": "123456789098",
"Arn": "arn:aws:iam::123456789098:user/dan"
}
It is indeed frustrating to debug without this, and it didn't used to exist, but now it does. Hurrah!

How to test credentials for AWS Command Line Tools

Is there a command/subcommand that can be passed to the aws utility that can 1) verify that the credentials in the ~/.aws/credentials file are valid, and 2) give some indication which user the credentials belong to? I'm looking for something generic that doesn't make any assumptions about the user having permissions to IAM or any specific service.
The use case for this is a deploy-time sanity check to make sure that the credentials are good. Ideally there would be some way to check the return value and abort the deploy if there are invalid credentials.
Use GetCallerIdentity:
aws sts get-caller-identity
Unlike other API/CLI calls it will always work, regardless of your IAM permissions.
You will get output in the following format:
{
"Account": "123456789012",
"UserId": "AR#####:#####",
"Arn": "arn:aws:sts::123456789012:assumed-role/role-name/role-session-name"
}
Exact ARN format will depend on the type of credentials, but often includes the name of the (human) user.
It uses the standard AWS CLI error codes giving 0 on success and 255 if you have no credentials.
There is a straightforward way - aws iam get-user would tell the details about who you are (the current IAM User) - provided the user has iam privileges.
There are couple of CLI calls which support --dry-run flag like aws ec2 run-instances which you tell you whether you have necessary config / cred to perform the operation.
There is also --auth-dry-run which Checks whether you have the required permissions for the command, without actually running the command. If you have the required permissions, the command returns DryRunOperation; otherwise, it returns UnauthorizedOperation. [ From AWS Documentation - Common Options ]
You would be able to list the IAM Access Keys from Management Console which you can cross check to see who has been assigned which key.
The best way to understand which user / role has what privileges is make use of IAM Policy Simulator.
I was in need of the same so I wrote aws-role
I also wanted that the command outputs session time remains before logout:
I used it in many shell scripts to automate my AWS use -- worked well for me.
my script parse ~/.aws/credentials
PS: also thinking to enhance it to support JSON output