Created
September 23, 2025 13:00
-
-
Save pkdavies/15badd215dbe3906fcc6b40e7eb20491 to your computer and use it in GitHub Desktop.
Find any buckets with a given name
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
import boto3 | |
import botocore | |
import configparser | |
import concurrent.futures | |
from botocore.exceptions import ClientError | |
AWS_CONFIG = os.path.expanduser('~/.aws/config') | |
AWS_CREDENTIALS = os.path.expanduser('~/.aws/credentials') | |
TARGET_BUCKET = None # Will be set from command line | |
def load_profiles(): | |
config = configparser.ConfigParser() | |
credentials = configparser.ConfigParser() | |
config.read(AWS_CONFIG) | |
credentials.read(AWS_CREDENTIALS) | |
# Extract role-based profiles from ~/.aws/config | |
role_profiles = { | |
section.replace('profile ', ''): dict(config[section]) | |
for section in config.sections() | |
if 'role_arn' in config[section] | |
} | |
# Extract credential profiles from ~/.aws/credentials | |
source_profiles = [section for section in credentials.sections()] | |
return role_profiles, source_profiles | |
def assume_role(profile_name, role_arn, source_profile): | |
try: | |
base_session = boto3.Session(profile_name=source_profile) | |
sts_client = base_session.client('sts') | |
response = sts_client.assume_role( | |
RoleArn=role_arn, | |
RoleSessionName=f"{profile_name}-via-{source_profile}" | |
) | |
# Return new session | |
return boto3.Session( | |
aws_access_key_id=response['Credentials']['AccessKeyId'], | |
aws_secret_access_key=response['Credentials']['SecretAccessKey'], | |
aws_session_token=response['Credentials']['SessionToken'] | |
) | |
except ClientError as e: | |
print(f"[β] Failed to assume {profile_name} via {source_profile}: {e.response['Error']['Code']}") | |
except Exception as e: | |
print(f"[β] Error assuming {profile_name} via {source_profile}: {e}") | |
return None | |
def scan_buckets(session, role_profile, source_profile): | |
s3 = session.client('s3') | |
try: | |
buckets = s3.list_buckets()['Buckets'] | |
except ClientError as e: | |
print(f"[!] Could not list buckets in {role_profile} via {source_profile}: {e}") | |
return False | |
for bucket in buckets: | |
name = bucket['Name'] | |
if name == TARGET_BUCKET: | |
print(f"[β] Bucket '{TARGET_BUCKET}' found in profile '{role_profile}' assumed via '{source_profile}'") | |
return True | |
return False | |
def main(): | |
import sys | |
global TARGET_BUCKET | |
if len(sys.argv) < 2: | |
print("Usage: python search.py <bucket-name>") | |
sys.exit(1) | |
TARGET_BUCKET = sys.argv[1] | |
role_profiles, source_profiles = load_profiles() | |
print(f"π Searching for bucket: {TARGET_BUCKET}") | |
print(f"π Trying {len(role_profiles)} roles against {len(source_profiles)} credential profiles...\n") | |
found = False | |
for role_profile, details in role_profiles.items(): | |
role_arn = details.get('role_arn') | |
for source_profile in source_profiles: | |
session = assume_role(role_profile, role_arn, source_profile) | |
if session: | |
success = scan_buckets(session, role_profile, source_profile) | |
if success: | |
found = True | |
break # Exit inner loop | |
if found: | |
break # Exit outer loop | |
if not found: | |
print(f"[β] Bucket '{TARGET_BUCKET}' not found in any profile/assumed role combination.") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment