CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/cloud/aws/enum_s3.rb
Views: 11655
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'aws-sdk-s3'
7
8
class MetasploitModule < Msf::Auxiliary
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => 'Amazon Web Services S3 instance enumeration',
14
'Description' => %q(
15
Provided AWS credentials, this module will call the authenticated
16
API of Amazon Web Services to list all S3 buckets associated
17
with the account
18
),
19
'Author' => ['Aaron Soto <[email protected]>'],
20
'License' => MSF_LICENSE
21
)
22
)
23
24
register_options(
25
[
26
OptString.new('REGION', [false, 'AWS Region (eg. "us-west-2")']),
27
OptString.new('ACCESS_KEY_ID', [true, 'AWS Access Key ID (eg. "AKIAXXXXXXXXXXXXXXXX")', '']),
28
OptString.new('SECRET_ACCESS_KEY', [true, 'AWS Secret Access Key (eg. "CA1+XXXXXXXXXXXXXXXXXXXXXX6aYDHHCBuLuV79")', ''])
29
]
30
)
31
end
32
33
def handle_aws_errors(e)
34
if e.class.module_parents.include?(Aws)
35
fail_with(Failure::UnexpectedReply, e.message)
36
else
37
raise e
38
end
39
end
40
41
def describe_s3_bucket(i)
42
print_good " Name: #{i.name}"
43
print_good " Creation Date: #{i.creation_date}"
44
print_good " # of Objects: #{@s3.list_objects_v2(bucket: i.name).contents.length}"
45
print_good " Region: #{@s3.get_bucket_location(bucket: i.name).location_constraint}"
46
47
begin
48
print_good " Website: /#{@s3.get_bucket_website(bucket: i.name).index_document.suffix}"
49
rescue Aws::S3::Errors::NoSuchWebsiteConfiguration
50
print_good " Website: (None)"
51
end
52
53
acl = @s3.get_bucket_acl(bucket: i.name)
54
print_good " Owner: #{acl.owner.display_name}"
55
print_good " Permissions:"
56
acl.grants.each do |i|
57
grantee = i.grantee.type == "CanonicalUser" ? "User" : i.grantee.type
58
grantee << " '#{i.grantee.display_name}'"
59
grantee << " (#{i.grantee.email_address})" unless i.grantee.email_address.nil?
60
grantee << " (#{i.grantee.uri})" unless i.grantee.uri.nil?
61
print_good " #{grantee} granted #{i.permission}"
62
end
63
print_status ''
64
end
65
66
def run
67
region = datastore['REGION']
68
69
@s3 = Aws::S3::Client.new(
70
region: "us-west-2", # This doesn't actually filter anything, but
71
# it's still required. Thanks AWS. :-(
72
access_key_id: datastore['ACCESS_KEY_ID'],
73
secret_access_key: datastore['SECRET_ACCESS_KEY']
74
)
75
76
buckets = @s3.list_buckets.buckets
77
unless buckets.length > 0
78
print_status 'No buckets found.'
79
return
80
end
81
82
print_good "Found #{buckets.count} buckets."
83
if region.nil?
84
buckets.each do |i|
85
describe_s3_bucket(i)
86
end
87
else
88
print_good "Listing buckets that match REGION '#{datastore['REGION']}':"
89
buckets.each do |i|
90
if @s3.get_bucket_location(bucket: i.name).location_constraint.starts_with? region
91
describe_s3_bucket(i)
92
end
93
end
94
end
95
print_status 'Done.'
96
rescue ::Exception => e
97
handle_aws_errors(e)
98
end
99
end
100
101