Skip to content

Commit 2ebffb9

Browse files
authored
Merge pull request #350 from 0xdabbad00/audit_mfa_policy
Audit mfa policy
2 parents af5726d + be99255 commit 2ebffb9

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

audit_config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ USER_HAS_NOT_USED_ACCESS_KEY_FOR_MAX_DAYS:
140140
is_global: True
141141
group: IAM
142142

143+
BAD_MFA_POLICY:
144+
title: Incorrect policy used to attempt to enforce MFA
145+
description: AWS had advised incorrect policies for enforcing MFA which allowed an attacker, if they compromised keys that were protected by this policy, to remove the MFA policy from themselves, or remove the existing MFA device and add their own.
146+
severity: High
147+
is_global: True
148+
group: IAM
149+
143150
DOMAIN_NOT_SET_TO_RENEW:
144151
title: Domain not set to autorenew
145152
description: This domain will no longer be under your control once it expires and may be taken over by someone else.

cloudmapper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import importlib
3232
import commands
3333

34-
__version__ = "2.5.1"
34+
__version__ = "2.5.2"
3535

3636
def show_help(commands):
3737
print("CloudMapper {}".format(__version__))

shared/audit.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from policyuniverse.policy import Policy
1313

14-
from shared.common import parse_arguments, query_aws, get_parameter_file, get_regions
14+
from shared.common import parse_arguments, query_aws, make_list, get_parameter_file, get_regions
1515
from shared.nodes import Account, Region
1616

1717

@@ -147,6 +147,34 @@ def audit_guardduty(findings, region):
147147
None,
148148
None))
149149

150+
def check_for_bad_policy(findings, region, arn, policy_text):
151+
for statement in make_list(policy_text['Statement']):
152+
# Checking for signatures of the bad MFA policy from https://web.archive.org/web/20170602002425/https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_users-self-manage-mfa-and-creds.html and https://github.com/awsdocs/iam-user-guide/blob/cfe14c674c494d07ba0ab952fe546fdd587da65d/doc_source/id_credentials_mfa_enable_virtual.md#permissions-required
153+
if statement.get('Sid', '') == 'AllowIndividualUserToManageTheirOwnMFA' or statement.get('Sid', '') == 'AllowIndividualUserToViewAndManageTheirOwnMFA':
154+
if 'iam:DeactivateMFADevice' in make_list(statement.get('Action', [])):
155+
findings.add(Finding(
156+
region,
157+
'BAD_MFA_POLICY',
158+
arn,
159+
policy_text))
160+
return
161+
elif statement.get('Sid', '') == 'BlockAnyAccessOtherThanAboveUnlessSignedInWithMFA':
162+
if 'iam:*' in make_list(statement.get('NotAction', [])):
163+
findings.add(Finding(
164+
region,
165+
'BAD_MFA_POLICY',
166+
arn,
167+
policy_text))
168+
return
169+
170+
def audit_iam_policies(findings, region):
171+
json_blob = query_aws(region.account, "iam-get-account-authorization-details", region)
172+
for policy in json_blob['Policies']:
173+
for policy_version in policy['PolicyVersionList']:
174+
if policy_version['IsDefaultVersion']:
175+
check_for_bad_policy(findings, region, policy['Arn'], policy_version['Document'])
176+
177+
150178
def audit_cloudtrail(findings, region):
151179
json_blob = query_aws(region.account, "cloudtrail-describe-trails", region)
152180
if len(json_blob['trailList']) == 0:
@@ -738,6 +766,7 @@ def audit(accounts):
738766
if region.name == 'us-east-1':
739767
audit_s3_buckets(findings, region)
740768
audit_cloudtrail(findings, region)
769+
audit_iam_policies(findings, region)
741770
audit_password_policy(findings, region)
742771
audit_root_user(findings, region)
743772
audit_users(findings, region)
@@ -764,6 +793,6 @@ def audit(accounts):
764793
findings.add(Finding(
765794
region,
766795
'EXCEPTION',
767-
None,
796+
e,
768797
resource_details={'exception': e, 'traceback': sys.exc_info()}))
769798
return findings

0 commit comments

Comments
 (0)