Files
metasploit-gs/lib/msf/core/post/azure.rb
T
2024-06-16 20:25:47 -04:00

98 lines
3.5 KiB
Ruby

# -*- coding: binary -*-
module Msf::Post::Azure
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
#
# Processes a hashtable (json) from azureProfile.json
#
# @param content [Hash] contents of a json file to process
# @return [Array]
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
#
# Processes a hashtable (json) generated via Save-AzContext or automatically
# generated in AzureRmContext.json
#
# @param content [Hash] contents of a json file to process
# @return [Array]
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
#
# Print any lines from a ConsoleHost_history.txt file that may have
# important information
#
# @param content [Str] contents of a ConsoleHost_history.txt file
# @return Array of strings to print to notify the user about
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
end