Auditing AWS Passwords

Table of Contents

• 1. Scoping

• 2. What the Scripts Do

• 3. Prerequisites

• 4. Step 1: Gather the Policy

• 5. Step 2: Evaluate the Policy

• 6. Reading the CSV

• 7. Common Exceptions and False Positives

• 8. How to Write Up the Finding

One of the first controls an IT Auditor learns is how to audit passwords in any number of IT systems. However, things have changed with the introduction of cloud platforms. This post covers the process and results of auditing AWS passwords.

The scripts are available at audit-labs/audit-tools.

1. Scoping

First thing first: scoping. To audit AWS passwords, we need to understand that AWS IAM password policies only apply to users with console access. This isn't the same as the password policy for an application built on top of AWS. It also has no effect on users who authenticate through IAM Identity Center, which delegates authentication to an external identity provider, such as Okta or Active Directory.

If the organization uses Identity Center exclusively and has no IAM users with passwords, you will need to perform a different procedure.

If they do have IAM users with console access, the script applies and is worth testing.

2. What the Scripts Do

The process runs in two steps:

1. gather_policy.sh calls the AWS CLI to fetch the current IAM password policy, captures metadata (timestamp, AWS account, region, caller identity), and writes everything to a JSON file. This file is evidence of the policy's current state.

2. evaluate_policy.py reads that JSON file, prompts you for the expected value of each setting, and exports a CSV report with a value of PASS or FAIL for each rule.

3. Prerequisites

To run this script, you'll need:

• Access to CloudShell or the AWS CLI utility installed and configured with credentials that have read access to iam:GetAccountPasswordPolicy and sts:GetCallerIdentity

• jq installed (used by the Bash script to merge JSON objects)

• Python 3 installed

• Optional: uv installed (used to run the Python script)

4. Step 1: Gather the Policy

Run the first script to pull the current policy from AWS:

By default, this writes the output to policy_report.json in the current directory. You can specify a custom path with the -o flag:

The output is a JSON file with two top-level keys: metadata and PasswordPolicy.

The metadata block is what ties this evidence to a specific account and point in time. The aws_caller_identity field shows who ran the script and in which account.

Figure 1: Policy Evaluation Results

5. Step 2: Evaluate the Policy

Pass the JSON file to the evaluation script:

The script will prompt you for each of the ten settings. Press Enter to skip any setting you don't need to test. For numeric settings like MinimumPasswordLength and MaxPasswordAge, the script treats your input as a minimum, so the actual value must be greater than or equal to your expected value to pass. Boolean settings require an exact match.

6. Reading the CSV

The CSV is your evidence. It includes the metadata header from the JSON file, so the account ID, timestamp, and caller identity are embedded directly in the file.

You may use this evidence in any form, but I suggest having your AWS contact screenshot the results directly within their CloudShell or AWS CLI session. This allows you to prove that the data was not modified after the script was run.

7. Common Exceptions and False Positives

• No policy defined: If gather_policy.sh exits with a NoSuchEntity error, the account has no IAM password policy configured. If you were expecting a password policy, document it as a missing control.

• HardExpiry: false: This setting controls whether users are locked out immediately when their password expires or given a grace period to change it. false is often intentional to avoid lockouts. Check the organization's policy before calling it a finding. Additionally, check if the organization has security exceptions in place before noting a deficiency.

• MaxPasswordAge and forced rotation: A 90-day rotation requirement is common in older policies and frameworks like CIS. NIST 800-63B no longer recommends forced rotation unless there's evidence of compromise. Know which framework you're auditing against before writing up a finding for this setting. Confirm with the organization to understand which framework they used to write their policy.

• PasswordReusePrevention: AWS allows a maximum of 24 previous passwords. If your organization's policy requires a higher number than AWS supports, document the platform limitation rather than raising it as a deficiency.

8. How to Write Up the Finding

If a setting fails, here's how to frame it:

• Deficiency: The MinimumPasswordLength setting in the AWS IAM password policy is configured to 6, which is below the organization's requirement of 8 characters.

• Root Cause: Due to {{ root cause }}, the policy was configured to enforce a MinimumPasswordLength of 6.

• Risk: Shorter passwords are more susceptible to brute-force and credential stuffing attacks, increasing the likelihood of unauthorized access to the AWS console.

• Evidence: Refer to policy_audit_.csv for documentation of testing.

The same structure applies to any other failing rule. For boolean settings, the deficiency is simply that the actual value does not match the expected value. For numeric settings, the deficiency is that the actual value falls below the required minimum.

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论