Lucene search
+L

Enumerate AWS S3

🗓️ 01 Dec 2025 12:51:31Reported by KittySploitType 
kittysploit
 kittysploit
🔗 kittysploit.com

KittySploit module to enumerate S3 buckets, list objects, and check permissions.

Refs
Code
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
AWS S3 Enumeration Module
Author: KittySploit Team
Version: 1.0.0

This module enumerates S3 buckets and their contents.
"""

from kittysploit import *
import json
from core.output_handler import print_info, print_success, print_error, print_warning

class Module(Post):
    """Enumerate AWS S3 buckets and objects"""
    
    __info__ = {
        "name": "Enumerate AWS S3",
        "description": "Enumerate S3 buckets, list objects, and check permissions",
        "author": "KittySploit Team",
        "version": "1.0.0",
        "session_type": SessionType.AWS,
    'agent': {
        'risk': 'intrusive',
        'effects': ['active_exploitation'],
        'expected_requests': 2,
        'reversible': False,
        'approval_required': True,
        'produces': ['risk_signals'],
        'cost': 1.5,
        'noise': 0.5,
        'value': 1.0,
        'requires':         {'min_endpoints': 0,
         'min_params': 0,
         'tech_hints_any': [],
         'tech_hints_all': [],
         'specializations_any': [],
         'risk_signals_any': [],
         'auth_session': False,
         'capabilities_any': [],
         'capabilities_all': [],
         'confidence_min': {},
         'confidence_min_any': {},
         'endpoint_pattern_any': [],
         'param_any': [],
         'api_surface_ready': False},
        'chain':         {'produces_capabilities': [],
         'consumes_capabilities': [],
         'option_bindings': {},
         'suggested_followups': []},
    },
    }
    
    list_buckets = OptBool(True, "List all S3 buckets", False)
    check_permissions = OptBool(True, "Check bucket permissions (ACL, policies)", False)
    list_objects = OptBool(False, "List objects in buckets (can be slow)", False)
    max_objects = OptInteger(100, "Maximum objects to list per bucket", False)
    check_public = OptBool(True, "Check if buckets are publicly accessible", False)
    output_file = OptString("", "Output file to save results (JSON format)", False)
    
    def run(self):
        """Run the S3 enumeration"""
        try:
            results = {}
            
            print_info("Starting AWS S3 enumeration...")
            print_info("=" * 80)
            
            # List buckets
            if self.list_buckets:
                print_info("\n[1] Listing S3 buckets...")
                buckets = self._list_buckets()
                if buckets:
                    results['buckets'] = buckets
                    print_success(f"Found {len(buckets)} S3 buckets")
                    for bucket in buckets:
                        name = bucket.get('Name', 'Unknown')
                        created = bucket.get('CreationDate', 'Unknown')
                        print_info(f"  - {name} (created: {created})")
                else:
                    print_info("No buckets found or access denied")
            
            # Check permissions and list objects
            if buckets and (self.check_permissions or self.list_objects or self.check_public):
                print_info("\n[2] Analyzing buckets...")
                for bucket in buckets:
                    bucket_name = bucket.get('Name')
                    if not bucket_name:
                        continue
                    
                    print_info(f"\n[*] Analyzing bucket: {bucket_name}")
                    bucket_info = {'name': bucket_name}
                    
                    # Check permissions
                    if self.check_permissions:
                        print_info(f"  Checking permissions...")
                        acl = self._get_bucket_acl(bucket_name)
                        policy = self._get_bucket_policy(bucket_name)
                        if acl:
                            bucket_info['acl'] = acl
                        if policy:
                            bucket_info['policy'] = policy
                    
                    # Check if public
                    if self.check_public:
                        is_public = self._check_bucket_public(bucket_name)
                        bucket_info['is_public'] = is_public
                        if is_public:
                            print_warning(f"  ⚠️  Bucket {bucket_name} is PUBLIC!")
                    
                    # List objects
                    if self.list_objects:
                        print_info(f"  Listing objects (max {self.max_objects})...")
                        objects = self._list_bucket_objects(bucket_name, self.max_objects)
                        if objects:
                            bucket_info['objects'] = objects
                            bucket_info['object_count'] = len(objects)
                            print_info(f"  Found {len(objects)} objects")
                            # Show first few objects
                            for obj in objects[:5]:
                                key = obj.get('Key', 'Unknown')
                                size = obj.get('Size', 0)
                                print_info(f"    - {key} ({size} bytes)")
                            if len(objects) > 5:
                                print_info(f"    ... and {len(objects) - 5} more")
                    
                    results['buckets'].append(bucket_info)
            
            # Summary
            print_info("\n" + "=" * 80)
            print_info("ENUMERATION SUMMARY")
            print_info("=" * 80)
            print_success(f"Found {len(results.get('buckets', []))} S3 buckets")
            
            public_buckets = [b for b in results.get('buckets', []) if b.get('is_public')]
            if public_buckets:
                print_warning(f"⚠️  Found {len(public_buckets)} PUBLIC buckets:")
                for bucket in public_buckets:
                    print_warning(f"  - {bucket.get('name')}")
            
            # Save to file if requested
            if self.output_file:
                try:
                    with open(self.output_file, 'w') as f:
                        json.dump(results, f, indent=2, default=str)
                    print_success(f"Results saved to {self.output_file}")
                except Exception as e:
                    print_error(f"Failed to save results: {e}")
            
            return True
            
        except Exception as e:
            print_error(f"Error during enumeration: {e}")
            import traceback
            traceback.print_exc()
            return False
    
    def _list_buckets(self):
        """List all S3 buckets"""
        cmd = "aws s3api list-buckets 2>/dev/null"
        result = self.cmd_execute(cmd)
        
        if result:
            try:
                data = json.loads(result)
                return data.get('Buckets', [])
            except:
                pass
        
        # Try Python boto3
        python_cmd = """
python3 -c "
import boto3, json
try:
    s3 = boto3.client('s3')
    response = s3.list_buckets()
    print(json.dumps(response.get('Buckets', [])))
except Exception as e:
    print('ERROR:', str(e))
" 2>/dev/null
"""
        result = self.cmd_execute(python_cmd)
        if result and 'ERROR' not in result:
            try:
                return json.loads(result)
            except:
                pass
        return []
    
    def _get_bucket_acl(self, bucket_name):
        """Get bucket ACL"""
        cmd = f"aws s3api get-bucket-acl --bucket {bucket_name} 2>/dev/null"
        result = self.cmd_execute(cmd)
        
        if result:
            try:
                return json.loads(result)
            except:
                pass
        return None
    
    def _get_bucket_policy(self, bucket_name):
        """Get bucket policy"""
        cmd = f"aws s3api get-bucket-policy --bucket {bucket_name} 2>/dev/null"
        result = self.cmd_execute(cmd)
        
        if result:
            try:
                data = json.loads(result)
                policy_str = data.get('Policy', '{}')
                return json.loads(policy_str)
            except:
                pass
        return None
    
    def _check_bucket_public(self, bucket_name):
        """Check if bucket is publicly accessible"""
        # Try to access bucket without credentials
        cmd = f"aws s3 ls s3://{bucket_name} --no-sign-request 2>&1 | head -1"
        result = self.cmd_execute(cmd)
        
        if result and 'AccessDenied' not in result and 'NoSuchBucket' not in result:
            return True
        
        # Check ACL
        acl = self._get_bucket_acl(bucket_name)
        if acl:
            grants = acl.get('Grants', [])
            for grant in grants:
                grantee = grant.get('Grantee', {})
                if grantee.get('Type') == 'Group' and 'AllUsers' in str(grantee):
                    return True
        
        return False
    
    def _list_bucket_objects(self, bucket_name, max_objects=100):
        """List objects in a bucket"""
        cmd = f"aws s3api list-objects-v2 --bucket {bucket_name} --max-items {max_objects} 2>/dev/null"
        result = self.cmd_execute(cmd)
        
        if result:
            try:
                data = json.loads(result)
                return data.get('Contents', [])
            except:
                pass
        
        # Try Python boto3
        python_cmd = f"""
python3 -c "
import boto3, json
try:
    s3 = boto3.client('s3')
    response = s3.list_objects_v2(Bucket='{bucket_name}', MaxKeys={max_objects})
    print(json.dumps(response.get('Contents', [])))
except Exception as e:
    print('ERROR:', str(e))
" 2>/dev/null
"""
        result = self.cmd_execute(python_cmd)
        if result and 'ERROR' not in result:
            try:
                return json.loads(result)
            except:
                pass
        return []


Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

10 Jul 2026 11:31Current
5.8Medium risk
Vulners AI Score5.8
0