Print token claims

This commit is contained in:
adfoster-r7 2021-10-12 16:59:07 +01:00
parent f28ced60ee
commit b306641755
No known key found for this signature in database
GPG Key ID: 3BD4FA3818818F04
3 changed files with 36 additions and 5 deletions

View File

@ -7,12 +7,15 @@ module Msf::Exploit::Remote::HTTP::Kubernetes::Enumeration
register_options(
[
Msf::OptString.new('NAMESPACE_LIST', [false, 'The default namespace list to iterate when the current token does not have the permission to retrieve the available namespaces', 'default,dev,staging,production,kube-node-lease,kube-lease,kube-system'])
Msf::OptString.new('NAMESPACE_LIST', [false, 'The default namespace list to iterate when the current token does not have the permission to retrieve the available namespaces', 'default,dev,staging,production,kube-public,kube-node-lease,kube-lease,kube-system'])
]
)
end
def enum_all
token_claims = parse_jwt(api_token)
output.print_claims(token_claims) if token_claims
enum_version
namespace_items = enum_namespaces
namespaces_name = namespace_items.map { |item| item.dig(:metadata, :name) }
@ -20,12 +23,11 @@ module Msf::Exploit::Remote::HTTP::Kubernetes::Enumeration
# If there's no permissions to access namespaces, we can use the current token's namespace,
# as well as trying some common namespaces
if namespace_items.empty?
token_claims = parse_jwt(api_token)
current_token_namespace = token_claims&.dig('kubernetes.io', 'namespace')
possible_namespaces = (datastore['NAMESPACE_LIST'].split(',') + [current_token_namespace]).uniq.compact
namespaces_name += possible_namespaces
output.print_error("No namespaces available. Attempting the current token's namespace and common namespaces: #{namespaces_name.join(', ')}")
output.print_error("Unable to extract namespaces. Attempting the current token's namespace and common namespaces: #{namespaces_name.join(', ')}")
end
# Split the information for each namespace separately
@ -163,7 +165,7 @@ module Msf::Exploit::Remote::HTTP::Kubernetes::Enumeration
path = store_loot('tls.key', 'text/plain', nil, tls_key, "#{loot_name}.key")
print_good("tls_key #{resource_name}: #{path}")
path = store_loot('tls.cert', 'text/plain', nil, tls_cert, "#{loot_name}.crt")
path = store_loot('tls.cert', 'application/x-pem-file', nil, tls_cert, "#{loot_name}.crt")
print_good("tls_cert #{resource_name}: #{path} (#{tls_subject || 'No Subject'})")
when Msf::Exploit::Remote::HTTP::Kubernetes::Secret::ServiceAccountToken
data = secret[:data].clone

View File

@ -23,6 +23,10 @@ class Msf::Exploit::Remote::HTTP::Kubernetes::Output::JSON
end
end
def print_claims(claims)
print_json(claims)
end
def print_version(version)
print_json(version)
end

View File

@ -32,9 +32,19 @@ class Msf::Exploit::Remote::HTTP::Kubernetes::Output::Table
end
end
def print_claims(claims)
table = create_table(
'Header' => 'Token Claims',
'Columns' => ['name', 'value'],
'Rows' => get_claim_as_rows(claims)
)
print_table(table)
end
def print_version(version)
table = create_table(
'Header' => 'Version',
'Header' => 'Server API Version',
'Columns' => ['name', 'value']
)
@ -173,4 +183,19 @@ class Msf::Exploit::Remote::HTTP::Kubernetes::Output::Table
output.print_line("#{' ' * indent_level}No rows") if table.rows.empty?
output.print_line
end
def get_claim_as_rows(hash, parent_keys: [])
return [] if hash.empty?
result = []
hash.each_pair do |key, value|
if value.is_a?(Hash)
result += get_claim_as_rows(value, parent_keys: parent_keys + [key])
else
result << [(parent_keys + [key.to_s]).join('.'), value]
end
end
result
end
end