本ブログは米国で2019年07月12日に公開されたUnit 42ブログ「USBCreator D-Bus Privilege Escalation in Ubuntu Desktop」の日本語翻訳です。

 

エグゼクティブサマリー

USBCreator D-Bus インターフェースの脆弱性により、sudoer グループのユーザーにアクセスできる攻撃者は、sudo プログラムに課されたパスワードセキュリティポリシーを回避できるようになります。この脆弱性により、攻撃者はパスワードを入力せず、root として任意のファイルを任意の内容で上書きすることができます。これが、たとえばシャドウファイルを上書きしたり、root パスワードを設定したりすることによる、容易な特権昇格につながります。この問題は、6 月の Unit 42からの脆弱性開示に応じ、Ubuntu が対応関連パッケージにパッチを作成したことにより解決済みです。

D-Bus の簡単な紹介

Ubuntu デスクトップは、プロセス間通信(IPC)を実現する仕組みとして D-Bus を利用しています。Ubuntu には、同時に実行されるメッセージ バスが複数存在します。システム バスは主に特権サービスに利用されるメッセージ バスで、本バスを通じてシステム全体にわたる関連サービスを公開します。もうひとつはログインユーザーごとに1つ用意されるセッションバスで、こちらのバスはその特定ユーザーだけに関連したサービスを公開するのに使われます。ここでは特権昇格を狙うので、より高い特権(たとえば root)で実行されることの多いシステム バスにフォーカスして調査していくことにします。D-Bus アーキテクチャは、セッション バスごとに1つの「ルーター」を使用し、対話先である関連サービスにクライアント メッセージをリダイレクトします。クライアントは、メッセージを伝達したいサービスのアドレスを指定する必要があります。

各サービスは、自身が公開するオブジェクトインターフェースによって定義されます。ここでいう「オブジェクト」とは、標準的なオブジェクト指向言語でいうところの「クラス インスタンス」と考えればよいでしょう。それぞれの一意なインスタンスは、オブジェクト パスを使って識別されます。オブジェクト パスは、サービスが公開している各オブジェクトを一意に特定するための、ファイル システム パスに似た文字列です。私たちの調査で役に立つ標準インターフェースは、org.freedesktop.DBus.Introspectable のインターフェースです。このインターフェースには Introspect (イントロスペクト) という機能があり、これを使うと対象オブジェクトがサポートするメソッドやシグナル、プロパティの XML 表現が返されます。本稿ではこの Introspect にフォーカスし、プロパティとシグナルについては取り上げません。

D-Bus インターフェースとの通信にあたって 2 つのツールを利用しました。1 つは gdbus という CLI ツールで、これを使えばスクリプト内から D-Bus に公開されているメソッドを簡単に呼び出すことができます。もう 1 つは D-Feet という Python ベースの GUI ツールで、各バスで利用可能なサービスを列挙し、各サービスに含まれるオブジェクトを確認するのに役立ちます。

 

図 1 D-Feet のメイン画面

 

図 2 D-Feet のインターフェース画面

D-Feet は優れたツールで、今回の調査に不可欠なツールであることが分かりました。図 1 の左ペインには、D-Bus デーモンのシステム バスに登録されているさまざまなサービスがすべて表示されています(上部にある [System Bus] の選択ボタンに注目してください)。org.debin.apt を選択すると、D-Feet は自動的に当該サービスで利用可能なすべてのオブジェクトを問い合わせます。特定オブジェクトを選択すれば、すべてのインターフェイス セットと、それぞれのセットに付随するメソッドのプロパティとシグナルが一覧表示されます(図 2 参照)。ここでは、各 IPC に公開されているメソッドのシグネチャも合わせて取得している点に着目してください。

また、各サービスをホストするプロセスの PID やコマンドラインも表示されますが、これは非常に便利な機能で、これを使えば調査対象サービスが実際により高い特権で実行されていることを検証できます。システム バス上のサービスの中には、root として実行されないものもあり、そうしたサービスは調査上さほど興味を引くものではないからです。

さらに D-Feet では、さまざまなメソッドを呼び出すこともできます。メソッド入力画面では、カンマ区切りで Python 式のリストを指定し、それらを呼び出し先関数のパラメータとして解釈させることができます (図 3 参照)。Python の型は D-Bus 型にマーシャリングされ、サービスに渡されます。

 

図 3 D-Feet 経由で D-Bus のメソッドを呼び出す

メソッドのなかには呼び出しを許可するために事前の認証が必要なものがありますが、ここでの目標はそもそも資格情報なしで特権昇格することなので、これらのメソッドについては取り上げません。

 

図 4 認可が必要なメソッド

また、サービスによっては、org.freedeskto.PolicyKit1 という名前の別の D-Bus サービスに問い合わせを行い、ユーザーに特定の操作の実行を許可するかどうかを確認するものがあります。 この org.freedeskto.PolicyKit1 (polkit) サービスについては後でまた取り上げます。

脆弱性

さまざまな D-Bus サービスを調査して、特権を持たないユーザーに代わって動作し、認証を必要とせず、ユーザー自身が入力を行うことができ、その結果操作に影響を及ぼすことができるような特権サービスを探しました。ユーザー入力を適切にサニタイズ・検証していないと、プログラム起動やファイルシステムの入出力実行などの単純な操作によって、システムが侵害されてしまう可能性があります。

脆弱性の見つかったサービスは com.ubuntu.USBCreator です。/com/ubuntu/USBCreator で表されるオブジェクトの下に Image メソッドがあります。このメソッドは、Ubuntu の USB Creator ツールが内部的に利用するものです。

 

図 5 com.ubuntu.USBCreator サービス

 

図 6 /com/ubuntu/USBCreator の Image メソッド

調べてみると、このサービスには特権があることがわかります。

 

図 7 サービスが特権を持つことが分かる

このサービスは Python で実装されているので、関連するソースコードを簡単に調べられます。まず、このメソッドと対話するために必要な特権はcom.ubuntu.usbcreator.image であることが分かります。ソースコードからは、要求しているユーザーにこの要求が許可されているかどうかについて、polkit に問い合わせが行われることが分かります(172行目)。

 

図 8 USBCreator のソース コード

polkit 設定ファイルをチェックすると、このメソッドとの対話を許可されているのは Unix グループ sudo であることが分かります(図 9 参照)。当該ファイルは /var/lib/polkit-1/localauthority の下にあります。より具体的には、私たちが調べているファイルは /var/lib/polkit-1/localauthority/10-vendor.d/com.ubuntu.desktop.pkla です。

 

図 9 26 行目から始まるセクションで com.ubuntu.usbcreator.image メソッドへのアクセスを許可するグループが指定されている

当該サービスのソースコードを調べると、Unix ツール dd の Python による実装が含まれていることがわかります。このツールの用途はいろいろありますが、異なるロケーション間でファイルをコピーするためにも使用することができます。メソッド _builtin_dd への入力は、ユーザー入力から直接取得されています。さらに、ソース パス、ターゲット パスのいずれにおいてもパスのサニタイズ チェックが行われておらず、パスワード プロンプトもありません。これによりユーザーは、ファイルシステム上の任意のファイルをパスワード入力を求められることなく root として上書きすることができます(図 10 参照)。

 

図 10 パスワードを入力することなく root としてファイルを作成

結論

この脆弱性が実際に悪用されたことは確認されていません。6 月 18 日に本脆弱性に対するパッチをリリースして以降、Ubuntu は USBCreator 起動にパスワード認証を要求します。パロアルトネットワークスのエンドポイント プロテクションとレスポンスを提供する製品 Traps は、Behavioral Threat Protection (BTP: 振る舞い分析による脅威防止) の仕組みを使い、本脆弱性の悪用を阻止できます。