Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/metasploit/framework/aws/client.rb
Views: 11784
require 'openssl'12module Metasploit3module Framework4module Aws5module Client6USER_AGENT = "aws-sdk-ruby2/2.6.27 ruby/2.3.2 x86_64-darwin15"7include Msf::Exploit::Remote::HttpClient89# because Post modules require these to be defined when including HttpClient10def register_autofilter_ports(ports=[]); end11def register_autofilter_hosts(ports=[]); end12def register_autofilter_services(services=[]); end1314def hexdigest(value)15if value.nil? || !value.instance_of?(String)16print_error "Unexpected value format"17return nil18end19digest = OpenSSL::Digest.new('SHA256')20if value.respond_to?(:read)21chunk = nil22chunk_size = 1024 * 1024 # 1 megabyte23digest.update(chunk) while chunk = value.read(chunk_size)24value.rewind25else26digest.update(value)27end28digest.hexdigest29end3031def hmac(key, value)32if key.nil? || !key.instance_of?(String) || value.nil? || !value.instance_of?(String)33print_error "Unexpected key/value format"34return nil35end36OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value)37end3839def hexhmac(key, value)40if key.nil? || !key.instance_of?(String) || value.nil? || !value.instance_of?(String)41print_error "Unexpected key/value format"42return nil43end44OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, value)45end4647def request_to_sign(headers, body_digest)48if headers.nil? || !headers.instance_of?(Hash) || body_digest.nil? || !body_digest.instance_of?(String)49return nil, nil50end51headers_block = headers.sort_by(&:first).map do |k, v|52v = "#{v},#{v}" if k == 'Host'53"#{k.downcase}:#{v}"54end.join("\n")55headers_list = headers.keys.sort.map(&:downcase).join(';')56flat_request = [ "POST", "/", '', headers_block + "\n", headers_list, body_digest].join("\n")57[headers_list, flat_request]58end5960def sign(creds, service, headers, body_digest, now)61date_mac = hmac("AWS4" + creds.fetch('SecretAccessKey'), now[0, 8])62region_mac = hmac(date_mac, datastore['Region'])63service_mac = hmac(region_mac, service)64credentials_mac = hmac(service_mac, 'aws4_request')65headers_list, flat_request = request_to_sign(headers, body_digest)66doc = "AWS4-HMAC-SHA256\n#{now}\n#{now[0, 8]}/#{datastore['Region']}/#{service}/aws4_request\n#{hexdigest(flat_request)}"6768signature = hexhmac(credentials_mac, doc)69[headers_list, signature]70end7172def auth(creds, service, headers, body_digest, now)73headers_list, signature = sign(creds, service, headers, body_digest, now)74"AWS4-HMAC-SHA256 Credential=#{creds.fetch('AccessKeyId')}/#{now[0, 8]}/#{datastore['Region']}/#{service}/aws4_request, SignedHeaders=#{headers_list}, Signature=#{signature}"75end7677def body(vars_post)78pstr = ""79vars_post.each_pair do |var, val|80pstr << '&' unless pstr.empty?81pstr << var82pstr << '='83pstr << val84end85pstr86end8788def headers(creds, service, body_digest, now = nil)89now = Time.now.utc.strftime("%Y%m%dT%H%M%SZ") if now.nil?90headers = {91'Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8',92'Accept-Encoding' => '',93'User-Agent' => USER_AGENT,94'X-Amz-Date' => now,95'Host' => datastore['RHOST'],96'X-Amz-Content-Sha256' => body_digest,97'Accept' => '*/*'98}99headers['X-Amz-Security-Token'] = creds['Token'] if creds['Token']100sign_headers = ['Content-Type', 'Host', 'User-Agent', 'X-Amz-Content-Sha256', 'X-Amz-Date']101auth_headers = headers.select { |k, _| sign_headers.include?(k) }102headers['Authorization'] = auth(creds, service, auth_headers, body_digest, now)103headers104end105106def print_hsh(hsh)107return if hsh.nil? || !hsh.instance_of?(Hash)108hsh.each do |key, value|109vprint_status "#{key}: #{value}"110end111end112113def print_results(doc, action)114response = "#{action}Response"115result = "#{action}Result"116resource = /[A-Z][a-z]+([A-Za-z]+)/.match(action)[1]117118if doc["ErrorResponse"] && doc["ErrorResponse"]["Error"]119print_error doc["ErrorResponse"]["Error"]["Message"]120return nil121end122123idoc = doc.fetch(response)124if idoc.nil? || !idoc.instance_of?(Hash)125print_error "Unexpected response structure"126return {}127end128idoc = idoc[result] if idoc[result]129idoc = idoc[resource] if idoc[resource]130131if idoc["member"]132idoc["member"].each do |x|133print_hsh x134end135else136print_hsh idoc137end138idoc139end140141def call_api(creds, service, api_params)142vprint_status("Connecting (#{datastore['RHOST']})...")143body = body(api_params)144body_length = body.length145body_digest = hexdigest(body)146begin147res = send_request_raw(148'method' => 'POST',149'data' => body,150'headers' => headers(creds, service, body_digest)151)152if res.nil?153print_error "#{peer} did not respond"154else155Hash.from_xml(res.body)156end157rescue => e158print_error e.message159end160end161162def call_iam(creds, api_params)163api_params['Version'] = '2010-05-08' unless api_params['Version']164call_api(creds, 'iam', api_params)165end166167def call_ec2(creds, api_params)168api_params['Version'] = '2015-10-01' unless api_params['Version']169call_api(creds, 'ec2', api_params)170end171172def call_sts(creds, api_params)173api_params['Version'] = '2011-06-15' unless api_params['Version']174call_api(creds, 'sts', api_params)175end176end177end178end179end180181182