AWS Authentication


Created: 09.09.2020

This article is about AWS authentication process and how this activity is logged within the system.

IAM

Stands for Identity Access Management. There are several types of IAM identities. They are usually called “Principal”. This can be either a User or a Role. It can even be a service or an account. Users can assume Roles. Instance Profile is basically a separate IAM Role assumed by this particular instance.

IAM role. Some entity (principal in AWS language) that can be assumed by others (users, services, instances, accounts). However assumes the role, is provided with temporary credentials.

❓ As far as I know, principals (which I suppose is very close to the term entity) has an ID and probably a AccessKey as well.

Roles do not exist on their own. No, they are not ally cats πŸˆβ€β¬›. Instead, when a principal (service, user, account etc) assumes a role, it is given temporary credentials that expire with time. These credentials, btw, are stored in the IMDS. That’s what it is for. AWS_ACCESS_KEY_ID for temp creds starts with a ASIA prefix.

❓ If some entity assumed some role, can these temp creds be used by other entity?

There are also ACLs (Access Control Lists), they have XML format and define which principals in other AWS accounts can access a resouce in question.

Nice diagram here showing how exactly AWS decides whether to grant access or not:

![[dfir/investigation/artefacts/accounts/aws-auth/images/diagram.png]]

In order to understand what permissions something has, you need to add identity, resource policy + session restrictions.

IAM Policies

Policies consist of statements: Effect (ALLOW or DENY), Actions (What’s about to be done) and Resource (What’s it to be done to).

Policy created can be assigned to a user, a group, a resource, other principal.

There are several types of policies.

Organization Service Control Policy (SCP). This is one of the major. It specifies the maximum permissions that can be granted to IB or RB policies within the organization. Below is an example of such policy. It basically doesn’t allow IAM actions applied to any of the resources in case the request is not coming from eu-west-1 region.

{ 
	"Version": "2022-08-06",
	"Statement": [
		{
			"Sid": "SCP Policy",
			"Effect": "Deny",
			"NotAction": "iam:*",
			"Resource": "*",
			"Condition": {
				"StringNotEquals": {
					"aws:RequestedRegion": "eu-west-1"
				}
			}
		}
	]
}

Resource-based. Describe principles that are allowed to touch this particular resource.

❗️ Not all resources support RB policies.

Example:

{  
	"Version": "2022-08-06",
	"Statement": [ 
		{
			 "Sid": "my-ec2 Resource-based Policy",
			 "Effect": "Allow",
			 "Action": [ 
				 "ec2:*" 
			 ], 
			"Principal": { 
				"AWS":[
					"arn:aws:iam::123456789:role/my-ec2",
					"arn:aws:iam::123456789:user/superadmin"
				]
}
		}
	]
}

Identity-based. Specify resources that these identities are allowed to touch. Example:

{  
	"Version": "2022-08-06",
	"Statement": [ 
		{
			 "Sid": "my-ec2 Identity-based Policy",
			 "Effect": "Allow",
			 "Action": [ 
				 "s3:*" 
			 ], 
			"Resource": "*" 
		}
	]
}

Session policy. Used when programmatically creating a session. Limits the permissions. First, one needs to create a session. Let’s say, Ezio is a product manager but needs to access some accounting information.aws sts assume-role --role-arn "arn:aws:iam::123456789:role/accountant" --role-session-name "accountant-alice-session" --policy file://policy.json.

--role-arn arn:aws:iam::123456789:role/accountant - it’s the IB policy. Resource policy is evaluated behind the scenes.

--policy file://policy.json is our session policy (if any).

The example above basically says the following: “I am Ezio and I want to become an accountant for a day to access some resource. May I?”. Example of such policy:

{  "Version": "2022-06-08",
   "Statement": [

     {
        "Effect": "Allow",
        "Action": ["s3:ListBucket"],
        "Resource": ["arn:aws:s3:::accountinginfo"],
        "Condition": { "StringLike":{ "s3:prefix":["ezio/*"] } } },

     {
       "Effect": "Allow",
       "Action": ["s3:GetObject"],
       "Resource": "arn:aws:s3:::accountinginfo/ezio/*" }

]}

Permissions boundary. This is very close to the SCP in that it limits the maximum permissions that can be granted to a principal.

Access control lists. ❗️ XML. Basically, RB policies but for cross-account stuff.

Access Decision Tree

The official doc’s here [2].

  1. Search for “Deny” within the scope. If found, game over. Nothing is allowed.
  2. Review the SCP (if applicable). Deby if something is there prohibiting the request.
  3. Review the resource policy (if any). If this principal is not allowed - tell him to bugger off.
  4. If there are any permissions boundary, evaluate them first. If something the principal is requesting is prohibited, deny the request alltogether.
  5. If these are temp credentials, evaluate the session policy. If anything is wrong, deny.
  6. Evaluate all of the IB policies associated with the principal.

Instance profile

Instance profile is a container of a signle IAM role. For EC2 instances. It’s assigned to one IAM role, which has a number of managed or inline policy permissions. These credentials can be accessed via IMDSv1: curl –s "http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name".

For IMDSv2: TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token) to retrieve the token and curl -H "X-aws-ec2-metadata-token: $TOKEN"http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name" set the value of a X-aws-ec2-metadata-token HTTP header to that retreived value.

⚠️ The above one didn’t work for me. Probably because of the well designed security restrictions.

Policy Types By Owner

AWS Managed Policies - shared between all AWS customers.

Customer Managed Policies - every customer withing AWS realm creates private policies that are managed by them.

Inline policies - owned by a principle and can’t be reused by other entities.

Login activity

For admin account go to IAM -> Credential report to see all the users and the following information:

  1. user name
  2. arn (acc N + username)
  3. user_creation_time
  4. password_enabled
  5. password_last_used
  6. password_last_changed
  7. password_next_rotation
  8. mfa_active
  9. access_key_1_active
  10. access_key_1_last_rotated
  11. access_key_1_last_used_date
  12. access_key_1_last_used_region
  13. access_key_1_last_used_service
  14. access_key_2_active
  15. access_key_2_last_rotated
  16. access_key_2_last_used_date
  17. access_key_2_last_used_region
  18. access_key_2_last_used_service
  19. cert_1_active
  20. cert_1_last_rotated
  21. cert_2_active
  22. cert_2_last_rotated

Tokens

On AWS there are several types of tokens.

IMDS

IMDSv2 tokens live for 6 hours, see here:

TheΒ PUTΒ request must include a header that specifies the time to live (TTL) for the token, in seconds, up to a maximum of six hours (21,600 seconds).

IMDSv1 doesn’t have token at all.

Access Tokens

Tokens for users can be configired, see here:

The duration, in seconds, that the credentials should remain valid. Acceptable durations for IAM user sessions range from 900 seconds (15 minutes) to 129,600 seconds (36 hours), with 43,200 seconds (12 hours) as the default.

For this use get-session-token with --duration-seconds option. This is for temp credentials only. These creds can’t get to IAM info (if no MFA is also included) or STS API, aka Security Token Service (other than AssumeRole or GetCallerIdentity).

AWS_ACCESS_KEY_ID for temp creds starts with a ASIA prefix.

Service usage activity

Also, you can go to IAM -> username -> Access Advisor tab to see the services that this user has access to and when these were last used.

userIdentity

userIdentity can be either AssumedRole or IAMUser.

An IAM administrator can configure AWS Security Token Service to require that users specify their identity when they use temporary credentials to assume roles.

AssumedRole

The user can either use their creds directly or use some role (policy instead). In this case, logs will also contain sessionContext.

IAMUser

πŸ“˜ BTFM

Login in via AWS CLI

Ensure you have AWS CLI installed.

export AWS_ACCESS_KEY_ID="ASIAJKJHASDKJHSDKJLA"  
export AWS_SECRET_ACCESS_KEY="akljhdljkhljhewhjjkhsd/s"
export AWS_SESSION_TOKEN="kajsdhkjsaha" # optional. AWS_SESSION_TOKEN is required with temp creds only.

aws help
# You'll see all available options. For example, you can run aws ec2 to see what you can do to the EC2 instances from within the CLI

Retieve Metadata from EC2

# ssh into the machine in question
ssh user@machineIPorDNSname
# when promted for the password for user, enter it (in case public key encryption is not being used)

# The next two commands are issued from the EC2's console

# IMDSv1
curl –s "http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name"

# IMDSv2
# to retrieve the token
TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token)
# set X-aws-ec2-metadata-token header to that value
 curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name"

Root

It’s not recommended to use root user for any activity on AWS unless it’s something that only root can done. https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html https://docs.aws.amazon.com/general/latest/gr/root-vs-iam.html#aws_tasks-that-require-root

References

[1] About IAM policies [2] Official AWS docs on policy evaluation order.