Skip to content

Commit

Permalink
added role_name to the database and changed user_arn to arn across al…
Browse files Browse the repository at this point in the history
…l files
  • Loading branch information
SpenGietz committed Sep 26, 2018
1 parent 26d6718 commit eb7445d
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 27 deletions.
6 changes: 4 additions & 2 deletions core/models.py
Expand Up @@ -21,7 +21,8 @@ class AWSKey(Base, ModelUpdateMixin):
session_id = Column(Integer, ForeignKey('pacu_session.id', ondelete='CASCADE'))

user_name = Column(Text)
user_arn = Column(Text)
role_name = Column(Text)
arn = Column(Text)
account_id = Column(Text)
user_id = Column(Text)
roles = Column(JSONType)
Expand All @@ -42,7 +43,8 @@ def get_fields_as_camel_case_dictionary(self):
# Deep copy because Permissions->allow_permissions and deny_permissions were dicts that were being passed as reference
return copy.deepcopy({
'UserName': self.user_name,
'UserArn': self.user_arn,
'RoleName': self.role_name,
'Arn': self.arn,
'AccountId': self.account_id,
'UserId': self.user_id,
'Roles': self.roles,
Expand Down
2 changes: 1 addition & 1 deletion modules/ebs__enum_volumes_snapshots/main.py
Expand Up @@ -126,7 +126,7 @@ def main(args, pacu_main):
session_aws_key.update(
pacu_main.database,
account_id=identity['Account'],
user_arn=identity['Arn'],
arn=identity['Arn'],
user_id=identity['UserId'],
)
except Exception as error:
Expand Down
8 changes: 4 additions & 4 deletions modules/iam__backdoor_assume_role/main.py
Expand Up @@ -72,16 +72,16 @@ def main(args, pacu_main):

if args.user_arns is None:
# Find out the current users ARN
# This should be moved into the creds array in the "UserArn" parameter for those set of keys that are running this module
# This should be moved into the creds array in the "Arn" parameter for those set of keys that are running this module
user = key_info()
active_aws_key = get_aws_key_by_alias(session.key_alias)

if 'UserArn' not in user or user['UserArn'] is None:
if 'Arn' not in user or user['Arn'] is None:
client = pacu_main.get_boto3_client('sts')
user_info = client.get_caller_identity()
active_aws_key.update(pacu_main.database, user_arn=user_info['Arn'], user_id=user_info['UserId'], account_id=user_info['Account'])
active_aws_key.update(pacu_main.database, arn=user_info['Arn'], user_id=user_info['UserId'], account_id=user_info['Account'])

user_arns.append(active_aws_key.user_arn)
user_arns.append(active_aws_key.arn)
else:
if ',' in args.user_arns:
user_arns.extend(args.user_arns.split(','))
Expand Down
86 changes: 66 additions & 20 deletions modules/iam__enum_permissions/main.py
Expand Up @@ -39,10 +39,10 @@

parser = argparse.ArgumentParser(add_help=False, description=module_info['description'])

parser.add_argument('--all-users', required=False, default=False, action='store_true', help='Run this module against every user in the account and store the results to ./sessions/[current_session_name]/downloads/confirmed_permissions/[user_name].json. This data can then be run against the privesc_scan module with the --offline flag enabled.')
parser.add_argument('--user-name', required=False, default=None, help='A single username of a user to run this module against. By default, the user to which the active AWS keys belong to will be used.')
# parser.add_argument('--group-name', required=False, default=None, help='The name of a group to run this module against. By default, this module will be run against the user which the active AWS keys belong to.')
# parser.add_argument('--policy-name', required=False, default=None, help='The name of a specific policy to run this module against. By default, this module will be run against the user which the active AWS keys belong to.')
parser.add_argument('--all-users', required=False, default=False, action='store_true', help='Run this module against every user in the account and store the results to ./sessions/[current_session_name]/downloads/confirmed_permissions/user-[user_name].json. This data can then be run against the privesc_scan module with the --offline flag enabled.')
parser.add_argument('--user-name', required=False, default=None, help='A single user name of a user to run this module against. By default, the active AWS keys will be used.')
parser.add_argument('--all-roles', required=False, default=False, action='store_true', help='Run this module against every role in the account and store the results to ./sessions/[current_session_name]/downloads/confirmed_permissions/role-[role_name].json. This data can then be run against the privesc_scan module with the --offline flag enabled.')
parser.add_argument('--role-name', required=False, default=None, help='A single role name of a role to run this module against. By default, the active AWS keys will be used.')


def main(args, pacu_main):
Expand All @@ -56,9 +56,14 @@ def main(args, pacu_main):
fetch_data = pacu_main.fetch_data
######

summary_data = {'users_confirmed': 0}
summary_data = {
'users_confirmed': 0,
'roles_confirmed': 0
}

users = []
roles = []

if args.all_users is True:
if fetch_data(['IAM', 'Users'], module_info['prerequisite_modules'][0], '--users') is False:
print('FAILURE')
Expand All @@ -84,19 +89,49 @@ def main(args, pacu_main):
}
})
summary_data['single_user'] = args.user_name
else:

if args.all_roles is True:
if fetch_data(['IAM', 'Roles'], module_info['prerequisite_modules'][0], '--roles') is False:
print('FAILURE')
print(' SUB-MODULE EXECUTION FAILED')
return
fetched_roles = session.IAM['Roles']
for role in fetched_roles:
roles.append({
'RoleName': role['RoleName'],
'PermissionsConfirmed': True,
'Permissions': {
'Allow': {},
'Deny': {}
}
})
elif args.role_name is not None:
roles.append({
'RoleName': args.role_name,
'PermissionsConfirmed': True,
'Permissions': {
'Allow': {},
'Deny': {}
}
})
summary_data['single_role'] = args.role_name

is_user = is_role = False

if not any([args.all_users, args.user_name, args.all_roles, args.role_name]):
client = pacu_main.get_boto3_client('sts')
identity = client.get_caller_identity()
active_aws_key = session.get_active_aws_key(pacu_main.database)

if re.match(r'arn:aws:iam::\d{12}:user/', identity['Arn']) is not None:
is_user = True
client = pacu_main.get_boto3_client('iam')
try:
user = client.get_user()
active_aws_key.update(
pacu_main.database,
user_name=user['User']['UserName'],
user_arn=identity['Arn'],
arn=identity['Arn'],
user_id=identity['UserId'],
account_id=identity['Account']
)
Expand All @@ -106,36 +141,47 @@ def main(args, pacu_main):
active_aws_key.update(
pacu_main.database,
user_name=username,
user_arn=identity['Arn'],
arn=identity['Arn'],
user_id=identity['UserId'],
account_id=identity['Account']
)
else:
# Update the information from get_caller_identity and exit
active_aws_key.update(
pacu_main.database,
user_arn=identity['Arn'],
arn=identity['Arn'],
user_id=identity['UserId'],
account_id=identity['Account']
)
return False
elif re.match(r'arn:aws:sts::\d{12}:assumed-role/', identity['Arn']) is not None:
# TODO: Find role info
is_role = True
active_aws_key.update(
pacu_main.database,
user_name=identity['User']['UserName'],
user_arn=identity['Arn'],
role_name=identity['Arn'].split(':assumed-role/')[1].split('/')[0],
role_arn=identity['Arn'],
user_id=identity['UserId'],
account_id=identity['Account']
)
else:
print('Not an IAM user or role. Exiting...\n')
return False
user = key_info(alias=session.key_alias)
user['PermissionsConfirmed'] = True
user['Permissions'] = {'Allow': {}, 'Deny': {}}
users.append(user)
summary_data['single_user'] = user['UserName']

if is_user:
user = key_info(alias=session.key_alias)
user['PermissionsConfirmed'] = True
user['Permissions'] = {'Allow': {}, 'Deny': {}}
users.append(user)
summary_data['single_user'] = user['UserName']
elif is_role:
roles.append({
'RoleName': role['RoleName'],
'PermissionsConfirmed': True,
'Permissions': {
'Allow': {},
'Deny': {}
}
})

# list-groups-for-user
# list-user-policies
Expand Down Expand Up @@ -321,7 +367,7 @@ def main(args, pacu_main):
active_aws_key.update(
pacu_main.database,
user_name=user['UserName'],
user_arn=user['UserArn'],
arn=user['Arn'],
user_id=user['UserId'],
groups=user['Groups'],
policies=user['Policies'],
Expand All @@ -333,10 +379,10 @@ def main(args, pacu_main):
if not os.path.exists('sessions/{}/downloads/confirmed_permissions/'.format(session.name)):
os.makedirs('sessions/{}/downloads/confirmed_permissions/'.format(session.name))

with open('sessions/{}/downloads/confirmed_permissions/{}.json'.format(session.name, user['UserName']), 'w+') as user_permissions_file:
with open('sessions/{}/downloads/confirmed_permissions/user-{}.json'.format(session.name, user['UserName']), 'w+') as user_permissions_file:
json.dump(user, user_permissions_file, indent=2, default=str)

print(' {}\'s permissions stored in {}.json'.format(user['UserName'], user['UserName']))
print(' {}\'s permissions stored in user-{}.json'.format(user['UserName'], user['UserName']))
except ClientError as error:
if error.response['Error']['Code'] == 'AccessDenied':
print(' FAILURE: MISSING REQUIRED AWS PERMISSIONS')
Expand Down

0 comments on commit eb7445d

Please sign in to comment.