Module: Msf::Post::Azure
- Defined in:
- lib/msf/core/post/azure.rb
Instance Method Summary collapse
-
#print_consolehost_history(content) ⇒ Object
Print any lines from a ConsoleHost_history.txt file that may have important information.
-
#process_context_contents(content) ⇒ Array
Processes a hashtable (json) generated via Save-AzContext or automatically generated in AzureRmContext.json.
-
#process_profile_file(content) ⇒ Array
Processes a hashtable (json) from azureProfile.json.
- #process_tokens_file(content) ⇒ Object
Instance Method Details
#print_consolehost_history(content) ⇒ Object
Print any lines from a ConsoleHost_history.txt file that may have important information
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/msf/core/post/azure.rb', line 75 def print_consolehost_history(content) # a list of strings which may contain secrets or other important information commands_of_value = [ 'System.Management.Automation.PSCredential', # for creating new credentials, may contain username/password 'ConvertTo-SecureString', # often used with passwords 'Connect-AzAccount', # may contain an access token in line or near it 'New-PSSession', # may indicate lateral movement to a new host 'commandToExecute', # when used with Set-AzVMExtension and a CustomScriptExtension, may show code execution '-ScriptBlock' # when used with Invoke-Command, may show code execution ] output = [] content.each_line.with_index do |line, index| commands_of_value.each do |command| if line.downcase.include? command.downcase output.append("Line #{index + 1} may contain sensitive information. Manual search recommended, keyword hit: #{command}") end end end output end |
#process_context_contents(content) ⇒ Array
Processes a hashtable (json) generated via Save-AzContext or automatically generated in AzureRmContext.json
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/msf/core/post/azure.rb', line 45 def process_context_contents(content) table_data = [] # make sure we have keys we expect to return table_data unless content.key? 'Contexts' content['Contexts'].each_value do |account| username = account.dig('Account', 'Id') type = account.dig('Account', 'Type') principal_secret = account.dig('Account', 'ExtendedProperties', 'ServicePrincipalSecret') # only in 'ServicePrincipal' types access_token = account.dig('Account', 'ExtendedProperties', 'AccessToken') graph_access_token = account.dig('Account', 'ExtendedProperties', 'GraphAccessToken') # example of parsing these out to get an expiration for the token # unless graph_access_token.nil? || graph_access_token.empty? # decoded_token = Msf::Exploit::Remote::HTTP::JWT.decode(graph_access_token) # graph_access_token_exp = Time.at(decoded_token.payload['exp']).to_datetime # end ms_graph_access_token = account.dig('Account', 'ExtendedProperties', 'MicrosoftGraphAccessToken') key_vault_token = account.dig('Account', 'ExtendedProperties', 'KeyVault') table_data.append([username, type, access_token, graph_access_token, ms_graph_access_token, key_vault_token, principal_secret]) end table_data end |
#process_profile_file(content) ⇒ Array
Processes a hashtable (json) from azureProfile.json
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/msf/core/post/azure.rb', line 27 def process_profile_file(content) table_data = [] # make sure we have keys we expect to return table_data unless content.key? 'subscriptions' content['subscriptions'].each do |item| table_data << [item['name'], item.dig('user', 'name'), item['environmentName']] end table_data end |
#process_tokens_file(content) ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# File 'lib/msf/core/post/azure.rb', line 4 def process_tokens_file(content) table_data = [] dic = {} content.each do |item| if dic.key?(item['userId']) dic[item['userId']] = dic[item['userId']] + 1 else dic[item['userId']] = 1 end end dic.each do |key, value| table_data << [file_path, key, value] end table_data end |