設定ミスのある Sudoers の悪用

LinuxBeginner
オンラインで実践に進む

はじめに

Linux システムにおいて、sudo コマンドは、標準ユーザーが別のユーザー(通常は root 管理者)のセキュリティ権限でプログラムを実行することを可能にします。システム管理者は、特定のユーザーがパスワードなしで特定のコマンドを root として実行できるように、/etc/sudoers ファイルを設定することがよくあります。これは通常、開発者が Web サーバーを再起動したり、システム全体でファイルを検索したりできるようにするなど、利便性を目的として行われます。

ここでのセキュリティ上の教訓は、sudo ルールは実際には「委任された信頼」であるということです。もし委任されたバイナリが管理者の想定よりも強力な機能を持っている場合、そのルールは単なる安全な操作の許可ではなく、実質的にシェルへのアクセス権を与えてしまう可能性があります。

しかし、こうした善意の管理上のショートカットは、深刻なセキュリティ脆弱性を引き起こす可能性があります。もしユーザーが、他のコマンドを実行したりシェルを起動したりする機能を持つバイナリ(find、vim、awk など)を実行できる場合、攻撃者はこの権限を悪用して制限されたコマンドから脱出し、完全な root シェルを取得できます。この手法は一般的に「シェルエスケープ」や「GTFOBins」エクスプロイトと呼ばれます。

この実験では、セキュリティ監査人の立場になり、現在のユーザーの sudo 権限を列挙し、設定ミスのある許可されたバイナリを特定し、それを悪用して root への権限昇格を行います。

Sudo 権限の確認 (sudo -l)

このステップでは、現在のアカウントに割り当てられている sudo 権限を列挙する方法を学びます。

Linux システムで権限昇格の機会を探る際、最初に行うチェックの一つは、現在のユーザーが root としてどのようなコマンドを実行できるかを確認することです。sudo コマンドには、実行ユーザーに対して許可されているコマンドと禁止されているコマンドを表示する -l (list) フラグが組み込まれています。

sudo の設定ミスは、推測をほとんど必要とせず、直接的かつ容易な権限昇格につながる可能性があるため、これは優先度の高いチェック項目です。

調査結果を記録するために、このコマンドの出力をプロジェクトディレクトリ内のテキストファイルにリダイレクトします。

次のコマンドを実行して sudo 権限をリストアップし、出力を sudo_privs.txt という名前のファイルに保存します。

sudo -l > /home/labex/project/sudo_privs.txt

次に、作成したファイルの内容を表示して権限を分析します。

cat /home/labex/project/sudo_privs.txt

以下のような出力が表示されるはずです。

Matching Defaults entries for labex on this host:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User labex may run the following commands on this host:
    (root) NOPASSWD: /usr/bin/find

環境によっては、find ルール以外にも追加の sudo エントリが表示される場合があります。この実験では、labex ユーザーがパスワードなし(NOPASSWD)で /usr/bin/find を root として実行できることを明示している行に注目してください。この特定の設定が、今後のステップでターゲットにするものです。

シェルエスケープのための許可されたバイナリの分析

このステップでは、/usr/bin/find バイナリを分析し、それがどのように悪用されて任意のコマンドを実行できるかを理解します。

find コマンドは、ディレクトリ階層内のファイルやディレクトリを検索するために使用される強力なユーティリティです。しかし、これには -exec という非常に柔軟なパラメータが含まれています。-exec フラグを使用すると、ユーザーは find が見つけたすべてのファイルに対して指定したコマンドを実行できます。

問題は find 自体が悪意のあるものではなく、その表現力が高いことにあります。適切に制限されていない限り、root 権限で実行可能な表現力の高いバイナリはすべて、シェルエスケープの候補となります。

重大なセキュリティ上の欠陥は、find が sudo で実行されたときに発生します。find が root として実行されている場合、-exec パラメータに渡されたコマンドもすべて root として実行されます。

この理論を検証するために、-exec パラメータを使用して whoami コマンドを実行してみましょう。whoami コマンドは、現在のユーザーの有効なユーザー名を表示するだけの単純なコマンドです。実行コンテキストを確認するために、出力をファイルにリダイレクトします。

次のコマンドを実行します。

sudo find . -exec whoami \; -quit > /home/labex/project/whoami.txt

このコマンドを分解してみましょう。sudo find . の部分は、現在のディレクトリ (.) を起点として find コマンドを root として実行します。-exec whoami \; の部分は、find に対して whoami コマンドを実行するように指示しており、\; は -exec 文を終了させるために必要です。最後に、-quit フラグは、最初のマッチが見つかった直後に find を終了させるよう指示しており、これによりディレクトリ内のすべてのファイルに対して whoami が何度も実行されるのを防ぎます。

次に、出力ファイルの内容を確認します。

cat /home/labex/project/whoami.txt

以下の出力が表示されるはずです。

root

これは、-exec に渡されたコマンドが root 権限で正常に実行されたことを裏付けています。

Sudo を使用したバイナリの実行

このステップでは、-exec の脆弱性を利用して、通常は root ユーザーのみに制限されている機密性の高いシステムファイルにアクセスします。

Linux システムで最も機密性の高いファイルの一つが /etc/shadow です。このファイルには、システム上のすべてのユーザーアカウントの暗号化されたパスワードハッシュが含まれています。標準ユーザーには、このファイルに対する読み取り権限はありません。攻撃者がこのファイルを読み取ることができれば、オフラインでパスワードハッシュをクラックしようと試みることができます。

sudo find を使用して root として任意のコマンドを実行できることが証明されたため、この手法を使用して /etc/shadow の内容を読み取ることができます。

-exec 文の中で head コマンドを使用して、shadow ファイルの最初の行(通常は root ユーザーのハッシュが含まれている)だけを読み取り、プロジェクトディレクトリに保存します。

次のコマンドを実行します。

sudo find /etc/shadow -exec head -n 1 {} \; -quit > /home/labex/project/shadow_head.txt

このコマンドにおいて、{} は find が現在処理しているファイル名(この場合は /etc/shadow)に置き換わるプレースホルダーとして機能します。

出力ファイルを読み取って、機密情報の抽出に成功したことを確認します。

cat /home/labex/project/shadow_head.txt

以下のような出力が表示され、shadow ファイルから root ユーザーのエントリが表示されるはずです。

root:*:19711:0:99999:7:::

設定ミスのある sudo エントリを悪用することで、ファイルシステムの権限を正常にバイパスできました。

Root シェルの起動

このステップでは、root シェルを起動してシステムを完全に侵害するという最終的なアクションを行います。

機密ファイルを読み取ることも危険ですが、権限昇格の究極の目標は、root として実行される対話型シェルを取得することです。これにより、攻撃者はシステム全体への無制限のアクセス権を得ることになります。

これを達成するために、-exec パラメータに whoami や head のような単純なコマンドを渡す代わりに、/bin/bash のようなシェル実行ファイルのパスを渡すことができます。

現実のシナリオでは、攻撃者は sudo find . -exec /bin/bash \; -quit を実行して、対話型の root ターミナルに直接ドロップします。しかし、この自動化された実験環境では、対話型シェルに移行すると実験の実行が一時停止してしまうため、別の方法をとります。

代わりに、-c フラグを使用して非対話モードで root bash シェルを起動します。これにより、新しい root シェルに直接コマンドを渡して実行し、システムを完全に侵害した証拠を保存できます。ここでは、現在のユーザーの ID とグループメンバーシップに関する詳細情報を提供する id コマンドを使用します。

次のコマンドを実行して root シェルを起動し、ID を記録します。

sudo find . -exec /bin/bash -c "id > /home/labex/project/pwned.txt" \; -quit

最後に、pwned.txt ファイルを読み取って、究極の権限昇格を確認します。

cat /home/labex/project/pwned.txt

出力には、シェルが root ユーザーおよびグループ ID で実行されていることが明確に示されているはずです。

uid=0(root) gid=0(root) groups=0(root)

おめでとうございます!設定ミスのある sudoers ファイルを悪用して、標準ユーザーから root への権限昇格に成功しました。

まとめ

この実験では、Linux 環境における sudoers ファイルの設定ミスに関連するセキュリティリスクを探りました。まず、ユーザーアカウントの sudo 権限を列挙し、find バイナリがパスワードなしで root として実行できることを特定しました。find コマンドの -exec パラメータの機能を理解することで、root 権限で任意のコマンドを実行することができました。この脆弱性の影響を実証するために、制限されたシステムファイルを読み取り、最終的には root シェルを起動してシステムを完全に侵害しました。この演習は、最小権限の原則を遵守し、不正な権限昇格を防ぐために sudo 設定を慎重に監査することの重要性を強調しています。