SHARE
TWEET

aws_escalate.py

h8rt3rmin8r Aug 19th, 2019 87 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python3
  2. from __future__ import print_function
  3. import boto3, argparse, os, sys, json, time
  4. from botocore.exceptions import ClientError
  5.  
  6. def main(args):
  7.     access_key_id = args.access_key_id
  8.     secret_access_key = args.secret_key
  9.     session_token = args.session_token
  10.  
  11.     if args.access_key_id is None or args.secret_key is None:
  12.         print('IAM keys not passed in as arguments, enter them below:')
  13.         access_key_id = input('  Access Key ID: ')
  14.         secret_access_key = input('  Secret Access Key: ')
  15.         session_token = input('  Session Token (Leave blank if none): ')
  16.         if session_token.strip() == '':
  17.             session_token = None
  18.  
  19.     # Begin permissions enumeration
  20.     current_user = None
  21.     users = []
  22.     client = boto3.client(
  23.         'iam',
  24.         aws_access_key_id=access_key_id,
  25.         aws_secret_access_key=secret_access_key,
  26.         aws_session_token=session_token
  27.     )
  28.     if args.all_users is True:
  29.         response = client.list_users()
  30.         for user in response['Users']:
  31.             users.append({'UserName': user['UserName'], 'Permissions': {'Allow': {}, 'Deny': {}}})
  32.         while 'IsTruncated' in response and response['IsTruncated'] is True:
  33.             response = client.list_users(
  34.                 Marker=response['Marker']
  35.             )
  36.             for user in response['Users']:
  37.                 users.append({'UserName': user['UserName'], 'Permissions': {'Allow': {}, 'Deny': {}}})
  38.     elif args.user_name is not None:
  39.         users.append({'UserName': args.user_name, 'Permissions': {'Allow': {}, 'Deny': {}}})
  40.     else:
  41.         current_user = client.get_user()['User']
  42.         current_user = {
  43.             'UserName': current_user['UserName'],
  44.             'Permissions': {
  45.                 'Allow': {},
  46.                 'Deny': {}
  47.             }
  48.         }
  49.         users.append(current_user)
  50.     print('Collecting policies for {} users...'.format(len(users)))
  51.     for user in users:
  52.         user['Groups'] = []
  53.         user['Policies'] = []
  54.         try:
  55.             policies = []
  56.  
  57.             ## Get groups that the user is in
  58.             try:
  59.                 res = client.list_groups_for_user(
  60.                     UserName=user['UserName']
  61.                 )
  62.                 user['Groups'] = res['Groups']
  63.                 while 'IsTruncated' in res and res['IsTruncated'] is True:
  64.                     res = client.list_groups_for_user(
  65.                         UserName=user['UserName'],
  66.                         Marker=groups['Marker']
  67.                     )
  68.                     user['Groups'] += res['Groups']
  69.             except Exception as e:
  70.                 print('List groups for user failed: {}'.format(e))
  71.                 user['PermissionsConfirmed'] = False
  72.  
  73.             ## Get inline and attached group policies
  74.             for group in user['Groups']:
  75.                 group['Policies'] = []
  76.                 ## Get inline group policies
  77.                 try:
  78.                     res = client.list_group_policies(
  79.                         GroupName=group['GroupName']
  80.                     )
  81.                     policies = res['PolicyNames']
  82.                     while 'IsTruncated' in res and res['IsTruncated'] is True:
  83.                         res = client.list_group_policies(
  84.                             GroupName=group['GroupName'],
  85.                             Marker=res['Marker']
  86.                         )
  87.                         policies += res['PolicyNames']
  88.                 except Exception as e:
  89.                     print('List group policies failed: {}'.format(e))
  90.                     user['PermissionsConfirmed'] = False
  91.                 # Get document for each inline policy
  92.                 for policy in policies:
  93.                     group['Policies'].append({ # Add policies to list of policies for this group
  94.                         'PolicyName': policy
  95.                     })
  96.                     try:
  97.                         document = client.get_group_policy(
  98.                             GroupName=group['GroupName'],
  99.                             PolicyName=policy
  100.                         )['PolicyDocument']
  101.                     except Exception as e:
  102.                         print('Get group policy failed: {}'.format(e))
  103.                         user['PermissionsConfirmed'] = False
  104.                     user = parse_document(document, user)
  105.  
  106.                 ## Get attached group policies
  107.                 attached_policies = []
  108.                 try:
  109.                     res = client.list_attached_group_policies(
  110.                         GroupName=group['GroupName']
  111.                     )
  112.                     attached_policies = res['AttachedPolicies']
  113.                     while 'IsTruncated' in res and res['IsTruncated'] is True:
  114.                         res = client.list_attached_group_policies(
  115.                             GroupName=group['GroupName'],
  116.                             Marker=res['Marker']
  117.                         )
  118.                         attached_policies += res['AttachedPolicies']
  119.                     group['Policies'] += attached_policies
  120.                 except Exception as e:
  121.                     print('List attached group policies failed: {}'.format(e))
  122.                     user['PermissionsConfirmed'] = False
  123.                 user = parse_attached_policies(client, attached_policies, user)
  124.  
  125.             ## Get inline user policies
  126.             policies = []
  127.             if 'Policies' not in user:
  128.                 user['Policies'] = []
  129.             try:
  130.                 res = client.list_user_policies(
  131.                     UserName=user['UserName']
  132.                 )
  133.                 policies = res['PolicyNames']
  134.                 while 'IsTruncated' in res and res['IsTruncated'] is True:
  135.                     res = client.list_user_policies(
  136.                         UserName=user['UserName'],
  137.                         Marker=res['Marker']
  138.                     )
  139.                     policies += res['PolicyNames']
  140.                 for policy in policies:
  141.                     user['Policies'].append({
  142.                         'PolicyName': policy
  143.                     })
  144.             except Exception as e:
  145.                 print('List user policies failed: {}'.format(e))
  146.                 user['PermissionsConfirmed'] = False
  147.             # Get document for each inline policy
  148.             for policy in policies:
  149.                 try:
  150.                     document = client.get_user_policy(
  151.                         UserName=user['UserName'],
  152.                         PolicyName=policy
  153.                     )['PolicyDocument']
  154.                 except Exception as e:
  155.                     print('Get user policy failed: {}'.format(e))
  156.                     user['PermissionsConfirmed'] = False
  157.                 user = parse_document(document, user)
  158.             ## Get attached user policies
  159.             attached_policies = []
  160.             try:
  161.                 res = client.list_attached_user_policies(
  162.                     UserName=user['UserName']
  163.                 )
  164.                 attached_policies = res['AttachedPolicies']
  165.                 while 'IsTruncated' in res and res['IsTruncated'] is True:
  166.                     res = client.list_attached_user_policies(
  167.                         UserName=user['UserName'],
  168.                         Marker=res['Marker']
  169.                     )
  170.                     attached_policies += res['AttachedPolicies']
  171.                 user['Policies'] += attached_policies
  172.             except Exception as e:
  173.                 print('List attached user policies failed: {}'.format(e))
  174.                 user['PermissionsConfirmed'] = False
  175.             user = parse_attached_policies(client, attached_policies, user)
  176.             user.pop('Groups', None)
  177.             user.pop('Policies', None)
  178.         except Exception as e:
  179.             print('Error, skipping user {}:\n{}'.format(user['UserName'], e))
  180.         print('  {}... done!'.format(user['UserName']))
  181.  
  182.     print('  Done.\n')
  183.  
  184.     # Begin privesc scanning
  185.     all_perms = [
  186.         'iam:AddUserToGroup',
  187.         'iam:AttachGroupPolicy',
  188.         'iam:AttachRolePolicy',
  189.         'iam:AttachUserPolicy',
  190.         'iam:CreateAccessKey',
  191.         'iam:CreatePolicyVersion',
  192.         'iam:CreateLoginProfile',
  193.         'iam:PassRole',
  194.         'iam:PutGroupPolicy',
  195.         'iam:PutRolePolicy',
  196.         'iam:PutUserPolicy',
  197.         'iam:SetDefaultPolicyVersion',
  198.         'iam:UpdateAssumeRolePolicy',
  199.         'iam:UpdateLoginProfile',
  200.         'sts:AssumeRole',
  201.         'ec2:RunInstances',
  202.         'lambda:CreateEventSourceMapping',
  203.         'lambda:CreateFunction',
  204.         'lambda:InvokeFunction',
  205.         'lambda:UpdateFunctionCode',
  206.         'dynamodb:CreateTable',
  207.         'dynamodb:PutItem',
  208.         'glue:CreateDevEndpoint',
  209.         'glue:UpdateDevEndpoint',
  210.         'cloudformation:CreateStack',
  211.         'datapipeline:CreatePipeline'
  212.     ]
  213.  
  214.     escalation_methods = {
  215.         'CreateNewPolicyVersion': {
  216.             'iam:CreatePolicyVersion': True
  217.         },
  218.         'SetExistingDefaultPolicyVersion': {
  219.             'iam:SetDefaultPolicyVersion': True
  220.         },
  221.         'CreateEC2WithExistingIP': {
  222.             'iam:PassRole': True,
  223.             'ec2:RunInstances': True
  224.         },
  225.         'CreateAccessKey': {
  226.             'iam:CreateAccessKey': True
  227.         },
  228.         'CreateLoginProfile': {
  229.             'iam:CreateLoginProfile': True
  230.         },
  231.         'UpdateLoginProfile': {
  232.             'iam:UpdateLoginProfile': True
  233.         },
  234.         'AttachUserPolicy': {
  235.             'iam:AttachUserPolicy': True
  236.         },
  237.         'AttachGroupPolicy': {
  238.             'iam:AttachGroupPolicy': True
  239.         },
  240.         'AttachRolePolicy': {
  241.             'iam:AttachRolePolicy': True,
  242.             'sts:AssumeRole': True
  243.         },
  244.         'PutUserPolicy': {
  245.             'iam:PutUserPolicy': True
  246.         },
  247.         'PutGroupPolicy': {
  248.             'iam:PutGroupPolicy': True
  249.         },
  250.         'PutRolePolicy': {
  251.             'iam:PutRolePolicy': True,
  252.             'sts:AssumeRole': True
  253.         },
  254.         'AddUserToGroup': {
  255.             'iam:AddUserToGroup': True
  256.         },
  257.         'UpdateRolePolicyToAssumeIt': {
  258.             'iam:UpdateAssumeRolePolicy': True,
  259.             'sts:AssumeRole': True
  260.         },
  261.         'PassExistingRoleToNewLambdaThenInvoke': {
  262.             'iam:PassRole': True,
  263.             'lambda:CreateFunction': True,
  264.             'lambda:InvokeFunction': True
  265.         },
  266.         'PassExistingRoleToNewLambdaThenTriggerWithNewDynamo': {
  267.             'iam:PassRole': True,
  268.             'lambda:CreateFunction': True,
  269.             'lambda:CreateEventSourceMapping': True,
  270.             'dynamodb:CreateTable': True,
  271.             'dynamodb:PutItem': True
  272.         },
  273.         'PassExistingRoleToNewLambdaThenTriggerWithExistingDynamo': {
  274.             'iam:PassRole': True,
  275.             'lambda:CreateFunction': True,
  276.             'lambda:CreateEventSourceMapping': True
  277.         },
  278.         'PassExistingRoleToNewGlueDevEndpoint': {
  279.             'iam:PassRole': True,
  280.             'glue:CreateDevEndpoint': True
  281.         },
  282.         'UpdateExistingGlueDevEndpoint': {
  283.             'glue:UpdateDevEndpoint': True
  284.         },
  285.         'PassExistingRoleToCloudFormation': {
  286.             'iam:PassRole': True,
  287.             'cloudformation:CreateStack': True
  288.         },
  289.         'PassExistingRoleToNewDataPipeline': {
  290.             'iam:PassRole': True,
  291.             'datapipeline:CreatePipeline': True
  292.         },
  293.         'EditExistingLambdaFunctionWithRole': {
  294.             'lambda:UpdateFunctionCode': True
  295.         }
  296.     }
  297.     import re
  298.     for user in users:
  299.         print('User: {}'.format(user['UserName']))
  300.         checked_perms = {'Allow': {}, 'Deny': {}}
  301.         # Preliminary check to see if these permissions have already been enumerated in this session
  302.         if 'Permissions' in user and 'Allow' in user['Permissions']:
  303.             # Are they an admin already?
  304.             if '*' in user['Permissions']['Allow'] and user['Permissions']['Allow']['*'] == ['*']:
  305.                 user['CheckedMethods'] = {'admin': {}, 'Confirmed':{}, 'Potential': {}}
  306.                 print('  Already an admin!\n')
  307.                 continue
  308.             for perm in all_perms:
  309.                 for effect in ['Allow', 'Deny']:
  310.                     if perm in user['Permissions'][effect]:
  311.                         checked_perms[effect][perm] = user['Permissions'][effect][perm]
  312.                     else:
  313.                         for user_perm in user['Permissions'][effect].keys():
  314.                             if '*' in user_perm:
  315.                                 pattern = re.compile(user_perm.replace('*', '.*'))
  316.                                 if pattern.search(perm) is not None:
  317.                                     checked_perms[effect][perm] = user['Permissions'][effect][user_perm]
  318.  
  319.         checked_methods = {
  320.             'Potential': [],
  321.             'Confirmed': []
  322.         }
  323.  
  324.         # Ditch each escalation method that has been confirmed not to be possible
  325.         for method in escalation_methods:
  326.             potential = True
  327.             confirmed = True
  328.             for perm in escalation_methods[method]:
  329.                 if perm not in checked_perms['Allow']: # If this permission isn't Allowed, then this method won't work
  330.                     potential = confirmed = False
  331.                     break
  332.                 elif perm in checked_perms['Deny'] and perm in checked_perms['Allow']: # Permission is both Denied and Allowed, leave as potential, not confirmed
  333.                     confirmed = False
  334.                 elif perm in checked_perms['Allow'] and perm not in checked_perms['Deny']: # It is Allowed and not Denied
  335.                     if not checked_perms['Allow'][perm] == ['*']:
  336.                         confirmed = False
  337.             if confirmed is True:
  338.                 print('  CONFIRMED: {}\n'.format(method))
  339.                 checked_methods['Confirmed'].append(method)
  340.             elif potential is True:
  341.                 print('  POTENTIAL: {}\n'.format(method))
  342.                 checked_methods['Potential'].append(method)
  343.         user['CheckedMethods'] = checked_methods
  344.         if checked_methods['Potential'] == [] and checked_methods['Confirmed'] == []:
  345.             print('  No methods possible.\n')
  346.  
  347.     now = time.time()
  348.     headers = 'CreateNewPolicyVersion,SetExistingDefaultPolicyVersion,CreateEC2WithExistingIP,CreateAccessKey,CreateLoginProfile,UpdateLoginProfile,AttachUserPolicy,AttachGroupPolicy,AttachRolePolicy,PutUserPolicy,PutGroupPolicy,PutRolePolicy,AddUserToGroup,UpdateRolePolicyToAssumeIt,PassExistingRoleToNewLambdaThenInvoke,PassExistingRoleToNewLambdaThenTriggerWithNewDynamo,PassExistingRoleToNewLambdaThenTriggerWithExistingDynamo,PassExistingRoleToNewGlueDevEndpoint,UpdateExistingGlueDevEndpoint,PassExistingRoleToCloudFormation,PassExistingRoleToNewDataPipeline,EditExistingLambdaFunctionWithRole'
  349.     file = open('all_user_privesc_scan_results_{}.csv'.format(now), 'w+')
  350.     for user in users:
  351.         if 'admin' in user['CheckedMethods']:
  352.             file.write(',{} (Admin)'.format(user['UserName']))
  353.         else:
  354.             file.write(',{}'.format(user['UserName']))
  355.     file.write('\n')
  356.     for method in headers.split(','):
  357.         file.write('{},'.format(method))
  358.         for user in users:
  359.             if method in user['CheckedMethods']['Confirmed']:
  360.                 file.write('Confirmed,')
  361.             elif method in user['CheckedMethods']['Potential']:
  362.                 file.write('Potential,')
  363.             else:
  364.                 file.write(',')
  365.         file.write('\n')
  366.     file.close()
  367.     print('Privilege escalation check completed. Results stored to ./all_user_privesc_scan_results_{}.csv'.format(now))
  368.  
  369. # https://stackoverflow.com/a/24893252
  370. def remove_empty_from_dict(d):
  371.     if type(d) is dict:
  372.         return dict((k, remove_empty_from_dict(v)) for k, v in d.items() if v and remove_empty_from_dict(v))
  373.     elif type(d) is list:
  374.         return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
  375.     else:
  376.         return d
  377.  
  378. # Pull permissions from each policy document
  379. def parse_attached_policies(client, attached_policies, user):
  380.     for policy in attached_policies:
  381.         document = get_attached_policy(client, policy['PolicyArn'])
  382.         if document is False:
  383.             user['PermissionsConfirmed'] = False
  384.         else:
  385.             user = parse_document(document, user)
  386.     return user
  387.  
  388. # Get the policy document of an attached policy
  389. def get_attached_policy(client, policy_arn):
  390.     try:
  391.         policy = client.get_policy(
  392.             PolicyArn=policy_arn
  393.         )['Policy']
  394.         version = policy['DefaultVersionId']
  395.         can_get = True
  396.     except Exception as e:
  397.         print('Get policy failed: {}'.format(e))
  398.         return False
  399.  
  400.     try:
  401.         if can_get is True:
  402.             document = client.get_policy_version(
  403.                 PolicyArn=policy_arn,
  404.                 VersionId=version
  405.             )['PolicyVersion']['Document']
  406.             return document
  407.     except Exception as e:
  408.         print('Get policy version failed: {}'.format(e))
  409.         return False
  410.  
  411. # Loop permissions and the resources they apply to
  412. def parse_document(document, user):
  413.     if type(document['Statement']) is dict:
  414.         document['Statement'] = [document['Statement']]
  415.     for statement in document['Statement']:
  416.         if statement['Effect'] == 'Allow':
  417.             if 'Action' in statement and type(statement['Action']) is list: # Check if the action is a single action (str) or multiple (list)
  418.                 statement['Action'] = list(set(statement['Action'])) # Remove duplicates to stop the circular reference JSON error
  419.                 for action in statement['Action']:
  420.                     if action in user['Permissions']['Allow']:
  421.                         if type(statement['Resource']) is list:
  422.                             user['Permissions']['Allow'][action] += statement['Resource']
  423.                         else:
  424.                             user['Permissions']['Allow'][action].append(statement['Resource'])
  425.                     else:
  426.                         if type(statement['Resource']) is list:
  427.                             user['Permissions']['Allow'][action] = statement['Resource']
  428.                         else:
  429.                             user['Permissions']['Allow'][action] = [statement['Resource']]
  430.                     user['Permissions']['Allow'][action] = list(set(user['Permissions']['Allow'][action])) # Remove duplicate resources
  431.             elif 'Action' in statement and type(statement['Action']) is str:
  432.                 if statement['Action'] in user['Permissions']['Allow']:
  433.                     if type(statement['Resource']) is list:
  434.                         user['Permissions']['Allow'][statement['Action']] += statement['Resource']
  435.                     else:
  436.                         user['Permissions']['Allow'][statement['Action']].append(statement['Resource'])
  437.                 else:
  438.                     if type(statement['Resource']) is list:
  439.                         user['Permissions']['Allow'][statement['Action']] = statement['Resource']
  440.                     else:
  441.                         user['Permissions']['Allow'][statement['Action']] = [statement['Resource']] # Make sure that resources are always arrays
  442.                 user['Permissions']['Allow'][statement['Action']] = list(set(user['Permissions']['Allow'][statement['Action']])) # Remove duplicate resources
  443.             if 'NotAction' in statement and type(statement['NotAction']) is list: # NotAction is reverse, so allowing a NotAction is denying that action basically
  444.                 statement['NotAction'] = list(set(statement['NotAction'])) # Remove duplicates to stop the circular reference JSON error
  445.                 for not_action in statement['NotAction']:
  446.                     if not_action in user['Permissions']['Deny']:
  447.                         if type(statement['Resource']) is list:
  448.                             user['Permissions']['Deny'][not_action] += statement['Resource']
  449.                         else:
  450.                             user['Permissions']['Deny'][not_action].append(statement['Resource'])
  451.                     else:
  452.                         if type(statement['Resource']) is list:
  453.                             user['Permissions']['Deny'][not_action] = statement['Resource']
  454.                         else:
  455.                             user['Permissions']['Deny'][not_action] = [statement['Resource']]
  456.                     user['Permissions']['Deny'][not_action] = list(set(user['Permissions']['Deny'][not_action])) # Remove duplicate resources
  457.             elif 'NotAction' in statement and type(statement['NotAction']) is str:
  458.                 if statement['NotAction'] in user['Permissions']['Deny']:
  459.                     if type(statement['Resource']) is list:
  460.                         user['Permissions']['Deny'][statement['NotAction']] += statement['Resource']
  461.                     else:
  462.                         user['Permissions']['Deny'][statement['NotAction']].append(statement['Resource'])
  463.                 else:
  464.                     if type(statement['Resource']) is list:
  465.                         user['Permissions']['Deny'][statement['NotAction']] = statement['Resource']
  466.                     else:
  467.                         user['Permissions']['Deny'][statement['NotAction']] = [statement['Resource']] # Make sure that resources are always arrays
  468.                 user['Permissions']['Deny'][statement['NotAction']] = list(set(user['Permissions']['Deny'][statement['NotAction']])) # Remove duplicate resources
  469.         if statement['Effect'] == 'Deny':
  470.             if 'Action' in statement and type(statement['Action']) is list:
  471.                 statement['Action'] = list(set(statement['Action'])) # Remove duplicates to stop the circular reference JSON error
  472.                 for action in statement['Action']:
  473.                     if action in user['Permissions']['Deny']:
  474.                         if type(statement['Resource']) is list:
  475.                             user['Permissions']['Deny'][action] += statement['Resource']
  476.                         else:
  477.                             user['Permissions']['Deny'][action].append(statement['Resource'])
  478.                     else:
  479.                         if type(statement['Resource']) is list:
  480.                             user['Permissions']['Deny'][action] = statement['Resource']
  481.                         else:
  482.                             user['Permissions']['Deny'][action] = [statement['Resource']]
  483.                     user['Permissions']['Deny'][action] = list(set(user['Permissions']['Deny'][action])) # Remove duplicate resources
  484.             elif 'Action' in statement and type(statement['Action']) is str:
  485.                 if statement['Action'] in user['Permissions']['Deny']:
  486.                     if type(statement['Resource']) is list:
  487.                         user['Permissions']['Deny'][statement['Action']] += statement['Resource']
  488.                     else:
  489.                         user['Permissions']['Deny'][statement['Action']].append(statement['Resource'])
  490.                 else:
  491.                     if type(statement['Resource']) is list:
  492.                         user['Permissions']['Deny'][statement['Action']] = statement['Resource']
  493.                     else:
  494.                         user['Permissions']['Deny'][statement['Action']] = [statement['Resource']] # Make sure that resources are always arrays
  495.                 user['Permissions']['Deny'][statement['Action']] = list(set(user['Permissions']['Deny'][statement['Action']])) # Remove duplicate resources
  496.             if 'NotAction' in statement and type(statement['NotAction']) is list: # NotAction is reverse, so allowing a NotAction is denying that action basically
  497.                 statement['NotAction'] = list(set(statement['NotAction'])) # Remove duplicates to stop the circular reference JSON error
  498.                 for not_action in statement['NotAction']:
  499.                     if not_action in user['Permissions']['Allow']:
  500.                         if type(statement['Resource']) is list:
  501.                             user['Permissions']['Allow'][not_action] += statement['Resource']
  502.                         else:
  503.                             user['Permissions']['Allow'][not_action].append(statement['Resource'])
  504.                     else:
  505.                         if type(statement['Resource']) is list:
  506.                             user['Permissions']['Allow'][not_action] = statement['Resource']
  507.                         else:
  508.                             user['Permissions']['Allow'][not_action] = [statement['Resource']]
  509.                     user['Permissions']['Allow'][not_action] = list(set(user['Permissions']['Allow'][not_action])) # Remove duplicate resources
  510.             elif 'NotAction' in statement and type(statement['NotAction']) is str:
  511.                 if statement['NotAction'] in user['Permissions']['Allow']:
  512.                     if type(statement['Resource']) is list:
  513.                         user['Permissions']['Allow'][statement['NotAction']] += statement['Resource']
  514.                     else:
  515.                         user['Permissions']['Allow'][statement['NotAction']].append(statement['Resource'])
  516.                 else:
  517.                     if type(statement['Resource']) is list:
  518.                         user['Permissions']['Allow'][statement['NotAction']] = statement['Resource']
  519.                     else:
  520.                         user['Permissions']['Allow'][statement['NotAction']] = [statement['Resource']] # Make sure that resources are always arrays
  521.                 user['Permissions']['Allow'][statement['NotAction']] = list(set(user['Permissions']['Allow'][statement['NotAction']])) # Remove duplicate resources
  522.     return user
  523.  
  524. if __name__ == '__main__':
  525.     parser = argparse.ArgumentParser(description='This script will fetch permissions for a set of users and then scan for permission misconfigurations to see what privilege escalation methods are possible. Available attack paths will be output to a .csv file in the same directory.')
  526.     parser.add_argument('--all-users', required=False, default=False, action='store_true', help='Run this module against every user in the account.')
  527.     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.')
  528.     parser.add_argument('--access-key-id', required=False, default=None, help='The AWS access key ID to use for authentication.')
  529.     parser.add_argument('--secret-key', required=False, default=None, help='The AWS secret access key to use for authentication.')
  530.     parser.add_argument('--session-token', required=False, default=None, help='The AWS session token to use for authentication, if there is one.')
  531.  
  532.     args = parser.parse_args()
  533.     main(args)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top