diff --git a/libs/brute.py b/libs/brute.py index f78b11a..455954a 100644 --- a/libs/brute.py +++ b/libs/brute.py @@ -293,7 +293,8 @@ def brute_autoscaling_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY): return generic_permission_bruteforcer(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, 'autoscaling', tests) # http://boto3.readthedocs.io/en/latest/reference/services/autoscaling-plans.html -# todo + + def brute_autoscaling_plans_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY): print("### Enumerating Autoscaling-Plans Permissions ###") tests = [('DescribeScalingPlans', 'describe_scaling_plans', (), {}, ), ] @@ -590,11 +591,10 @@ def brute_ec2_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY): ('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-east1', 'Size': 8, 'DryRun': True}, ), + ('CreateVolume', 'create_volume', (), {'AvailabilityZone': 'us-east-1', 'Size': 8, 'DryRun': True}, ), ('DescribeSnapshots', 'describe_snapshots', (), {'DryRun': True, 'OwnerIds': ['self', ]}, ), ('CreateSnapshot', 'create_snapshot', (), {'VolumeId': 'vol-05777eab71bc97dcb', 'DryRun': True}, ), ('DescribeAccountAttributes', 'describe_account_attributes', (), {'DryRun': True}, ), - ('DescribeAccounts', 'describe_addresses', (), {'DryRun': True}, ), ('DescribeAddresses', 'describe_addresses', (), {'DryRun': True}, ), ('DescribeAvailabilityZones', 'describe_availability_zones', (), {'DryRun': True}, ), ('DescribeBundleTasks', 'describe_bundle_tasks', (), {'DryRun': True}, ), @@ -605,7 +605,7 @@ def brute_ec2_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY): ('DescribeEgressOnlyInternetGateways', 'describe_egress_only_internet_gateways', (), {'DryRun': True}, ), # The above is more than enough to decide that all/almost all EC2 permissions are there but - # I'm putting all of them so they can be used for infomration gathering later and i can keep the + # I'm putting all of them so they can be used for information gathering later and i can keep the # ec2 tests blocks consistent across modules ('DescribeExportTasks', 'describe_export_tasks', (), {}, ), @@ -618,6 +618,7 @@ def brute_ec2_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY): ('DescribeInternetGateways', 'describe_internet_gateways', (), {'DryRun': True}, ), ('DescribeKeyPairs', 'describe_key_pairs', (), {'DryRun': True}, ), ('CreateKeyPair', 'create_key_pair', (), {'KeyName': 'asdfg12345', 'DryRun': True}, ), + ('DescribeLaunchTemplates', 'describe_launch_templates', (), {'DryRun': True}, ), ('DescribeMovingAddresses', 'describe_moving_addresses', (), {'DryRun': True}, ), ('DescribeNatGateways', 'describe_nat_gateways', (), {}, ), ('DescribeNetworkAcls', 'describe_network_acls', (), {'DryRun': True}, ), diff --git a/libs/ec2.py b/libs/ec2.py index 5c0afd7..c63e60c 100644 --- a/libs/ec2.py +++ b/libs/ec2.py @@ -157,3 +157,80 @@ def get_instance_volume_details2(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY): print(e) except KeyboardInterrupt: print("CTRL-C received, exiting...") + +def describe_addresses(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY): + try: + for region in regions: + client = boto3.client('ec2', aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, region_name=region) + response = client.describe_addresses() + # print(response) + if response.get('Addresses') is None: + print("{} likely does not have EC2 permissions\n" .format(AWS_ACCESS_KEY_ID)) + elif len(response['Addresses']) <= 0: + print("[-] DescribeAddresses allowed for {} but no results [-]" .format(region)) + else: + # print (response) + print("[+] Listing Addresses for region: {} [+]" .format(region)) + for r in response['Addresses']: + pp.pprint(r) + except botocore.exceptions.ClientError as e: + if e.response['Error']['Code'] == 'UnauthorizedOperation': + print('{} : (UnauthorizedOperation) when calling the DescribeInstances-- sure you have ec2 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(e) + except KeyboardInterrupt: + print("CTRL-C received, exiting...") + +def describe_network_interfaces(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY): + try: + for region in regions: + client = boto3.client('ec2', aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, region_name=region) + response = client.describe_network_interfaces() + # print(response) + if response.get('NetworkInterfaces') is None: + print("{} likely does not have EC2 permissions\n" .format(AWS_ACCESS_KEY_ID)) + elif len(response['NetworkInterfaces']) <= 0: + print("[-] DescribeNetworkInterfaces allowed for {} but no results [-]" .format(region)) + else: + # print (response) + print("[+] Listing Network Interfaces for region: {} [+]" .format(region)) + for r in response['NetworkInterfaces']: + pp.pprint(r) + except botocore.exceptions.ClientError as e: + if e.response['Error']['Code'] == 'UnauthorizedOperation': + print('{} : (UnauthorizedOperation) when calling the DescribeInstances-- sure you have ec2 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(e) + except KeyboardInterrupt: + print("CTRL-C received, exiting...") + + +def describe_route_tables(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY): + try: + for region in regions: + client = boto3.client('ec2', aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, region_name=region) + response = client.describe_route_tables() + # print(response) + if response.get('RouteTables') is None: + print("{} likely does not have EC2 permissions\n" .format(AWS_ACCESS_KEY_ID)) + elif len(response['RouteTables']) <= 0: + print("[-] DescribeRouteTables allowed for {} but no results [-]" .format(region)) + else: + # print (response) + print("[+] Listing Route Tables for region: {} [+]" .format(region)) + for r in response['RouteTables']: + pp.pprint(r) + except botocore.exceptions.ClientError as e: + if e.response['Error']['Code'] == 'UnauthorizedOperation': + print('{} : (UnauthorizedOperation) when calling the DescribeInstances-- sure you have ec2 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(e) + except KeyboardInterrupt: + print("CTRL-C received, exiting...") + diff --git a/modules/ec2.py b/modules/ec2.py index 5e6a9c1..bb289ca 100644 --- a/modules/ec2.py +++ b/modules/ec2.py @@ -51,3 +51,22 @@ This function is used to list EBS volumes and whether or not they are encrypted. def step_ec2_review_encrypted_volumes(): review_encrypted_volumes(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) + +''' +This function is used to describe ec2 network addresses. +''' + + +def step_ec2_describe_addresses(): + describe_addresses(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) + +''' +This function is used to describe ec2 network interfaces. +''' + +def step_ec2_describe_network_interfaces(): + describe_network_interfaces(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) + + +def step_ec2_describe_route_tables(): + describe_route_tables(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) diff --git a/modules/recon.py b/modules/recon.py index c4d7b28..2ea4ab9 100644 --- a/modules/recon.py +++ b/modules/recon.py @@ -10,9 +10,9 @@ def step_recon_all(): brute_acm_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) # AlexaForBusiness brute_apigateway_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) - # Application Auto Scaling + # Application Auto Scaling - no usable functions brute_appstream_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) - # AppSync no usable functions + # AppSync - no usable functions brute_athena_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) brute_autoscaling_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) brute_autoscaling_plans_permissions(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)