From 6ccbc5783b8c172a9a651121bf94bbdbf440b7cf Mon Sep 17 00:00:00 2001 From: Jacob Hammontree Date: Sat, 18 Dec 2021 09:29:42 -0500 Subject: [PATCH 1/2] Added --profile option for switching AWS profiles --- S3Scanner/S3Service.py | 10 ++++++---- S3Scanner/__main__.py | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/S3Scanner/S3Service.py b/S3Scanner/S3Service.py index 2ac38d1..487c8df 100644 --- a/S3Scanner/S3Service.py +++ b/S3Scanner/S3Service.py @@ -2,7 +2,7 @@ This will be a service that the client program will instantiate to then call methods passing buckets """ -from boto3 import client # TODO: Limit import to just boto3.client, probably +from boto3 import client, session as boto_session # TODO: Limit import to just boto3.client, probably from S3Scanner.S3Bucket import S3Bucket, BucketExists, Permission, S3BucketObject from botocore.exceptions import ClientError import botocore.session @@ -23,7 +23,7 @@ class S3Service: def __init__(self, forceNoCreds=False, endpoint_url='https://s3.amazonaws.com', verify_ssl=True, - endpoint_address_style='path'): + endpoint_address_style='path', profile='default'): """ Service constructor @@ -49,7 +49,9 @@ def __init__(self, forceNoCreds=False, endpoint_url='https://s3.amazonaws.com', raise InvalidEndpointException(message=f"Endpoint '{self.endpoint_url}' does not appear to be S3-compliant") # Check for AWS credentials - session = botocore.session.get_session() + session = boto_session.Session() + if profile in session.available_profiles: # use provided profile, if it is availble to use + session = boto_session.Session(profile_name=profile) if forceNoCreds or session.get_credentials() is None or session.get_credentials().access_key is None: self.aws_creds_configured = False self.s3_client = client('s3', @@ -58,7 +60,7 @@ def __init__(self, forceNoCreds=False, endpoint_url='https://s3.amazonaws.com', endpoint_url=self.endpoint_url, use_ssl=use_ssl, verify=verify_ssl) else: self.aws_creds_configured = True - self.s3_client = client('s3', config=Config(s3={'addressing_style': self.endpoint_address_style}, connect_timeout=3, + self.s3_client = session.client('s3', config=Config(s3={'addressing_style': self.endpoint_address_style}, connect_timeout=3, retries={'max_attempts': 2}), endpoint_url=self.endpoint_url, use_ssl=use_ssl, verify=verify_ssl) diff --git a/S3Scanner/__main__.py b/S3Scanner/__main__.py index ad9c069..c044880 100644 --- a/S3Scanner/__main__.py +++ b/S3Scanner/__main__.py @@ -127,6 +127,7 @@ def main(): parser.add_argument('--endpoint-address-style', '-s', dest='endpoint_address_style', choices=['path', 'vhost'], default='path', help='Address style to use for the endpoint. Default: path') parser.add_argument('--insecure', '-i', dest='verify_ssl', action='store_false', help='Do not verify SSL') + parser.add_argument('--profile', '-p', dest='aws_profile',default='default', help='AWS profile to use (defaults to `default`)') subparsers = parser.add_subparsers(title='mode', dest='mode', help='(Must choose one)') # Scan mode @@ -160,7 +161,7 @@ def main(): s3service = None anons3service = None try: - s3service = S3Service(endpoint_url=args.endpoint_url, verify_ssl=args.verify_ssl, endpoint_address_style=args.endpoint_address_style) + s3service = S3Service(endpoint_url=args.endpoint_url, verify_ssl=args.verify_ssl, endpoint_address_style=args.endpoint_address_style,profile=args.aws_profile) anons3service = S3Service(forceNoCreds=True, endpoint_url=args.endpoint_url, verify_ssl=args.verify_ssl, endpoint_address_style=args.endpoint_address_style) except InvalidEndpointException as e: print(f"Error: {e.message}") From 54950cbae5b406b6b0661dafccf6399a2107e67c Mon Sep 17 00:00:00 2001 From: Jacob Hammontree Date: Sun, 30 Jan 2022 07:37:09 -0500 Subject: [PATCH 2/2] Added a check to make sure the passed profile exists --- S3Scanner/S3Service.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/S3Scanner/S3Service.py b/S3Scanner/S3Service.py index 487c8df..2105703 100644 --- a/S3Scanner/S3Service.py +++ b/S3Scanner/S3Service.py @@ -52,6 +52,10 @@ def __init__(self, forceNoCreds=False, endpoint_url='https://s3.amazonaws.com', session = boto_session.Session() if profile in session.available_profiles: # use provided profile, if it is availble to use session = boto_session.Session(profile_name=profile) + else: + print(f"Error: profile \"{profile}\" not found in ~/.aws/credentials") + exit(1) + if forceNoCreds or session.get_credentials() is None or session.get_credentials().access_key is None: self.aws_creds_configured = False self.s3_client = client('s3',