SUID バイナリの悪用

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

はじめに

Linux や Unix 系システムにおいて、ファイルパーミッションはセキュリティの根幹を成す要素です。その中でも特別なパーミッションの一つに、SUID(Set Owner User ID)ビットがあります。バイナリファイルに SUID ビットが設定されている場合、そのファイルを実行したユーザーの権限ではなく、ファイルの所有者の権限で実行されます。

これは、パスワードを更新するために root アクセスを必要とする passwd コマンドのように、特定の正当なシステム機能には不可欠なものです。しかし、設定を誤ると深刻なセキュリティリスクとなります。システム管理者が誤って find、vim、bash などの標準的なユーティリティに SUID ビットを設定してしまうと、攻撃者はこれらのツールを悪用して root ユーザーとしてコマンドを実行し、権限昇格(Privilege Escalation)と呼ばれるシステム全体の乗っ取りが可能になります。

SUID が危険なのは、プログラム実行時の権限コンテキストそのものを変更してしまう点にあります。もしそのプログラムが他のコマンドやシェルを起動できる場合、その権限が外部へ漏洩してしまうのです。

この実験では、セキュリティリサーチャーの視点に立ちます。Linux ファイルシステムをスキャンして SUID ビットが設定されたバイナリを特定し、脆弱な設定ミスを見つけ出し、有名な GTFOBins プロジェクトの手法を用いて root 権限への昇格を試みます。

SUID バイナリの検索 (find)

このステップでは、SUID パーミッションビットが設定されたバイナリを Linux ファイルシステムから検索する方法を学びます。

これらのファイルを見つけるには、組み込みの find コマンドを使用します。find コマンドは非常に強力で、特定のパーミッションに基づいてファイルを検索できます。ルートディレクトリ / から開始し、SUID ビット(8 進数値 4000 で表される)が有効になっているファイルを検索します。

SUID ファイルの列挙は、一般ユーザーの代わりに高い権限で実行されるプログラムを迅速に明らかにできるため、権限昇格の際の標準的な手順となっています。

ターミナルで以下のコマンドを実行し、SUID バイナリを検索して、結果をプロジェクトディレクトリ内の suid_results.txt という名前のテキストファイルに保存してください。

find / -perm -4000 -type f 2> /dev/null > ~/project/suid_results.txt

このコマンドの内容を解説します。/ はファイルシステムの最上位から検索を開始することを意味します。-perm -4000 フラグは、SUID ビットが設定されているファイルを具体的に探します。-type f フラグは、ディレクトリではなく通常のファイルのみを対象にすることを指定します。最後に、2>/dev/null は、「Permission denied(許可が拒否されました)」というエラーメッセージをブラックホール(/dev/null)に捨てて、出力をクリーンに保つための便利なテクニックです。> 記号は、クリーンな出力をテキストファイルにリダイレクトします。

それでは、作成したファイルの中身を表示して、どのバイナリに SUID ビットが設定されているか確認しましょう。

cat ~/project/suid_results.txt

以下のような出力が表示されます。

/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/openssh/ssh-keysign
/usr/bin/chfn
/usr/bin/find
/usr/bin/chsh
/usr/bin/passwd
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/su
/usr/bin/mount
/usr/bin/umount

リストをよく見てください。passwd や su のように、SUID ビットが設定されていることが想定されるものも多く含まれています。しかし、その中に一つ、非常に異質で危険な可能性のあるバイナリがあります。

悪用可能なバイナリの特定 (GTFOBins)

このステップでは、検索結果を分析し、どのバイナリが悪用可能かを特定します。

前ステップの出力を見ると、リストの中に /usr/bin/find があることに気づくでしょう。find コマンドはファイルを検索するための標準的なユーティリティであり、通常動作において root 権限を必要とすることは一切ありません。これに SUID ビットが設定されていることは、重大なセキュリティ設定ミスです。

この判断は重要です。すべての SUID バイナリが悪用可能というわけではありませんが、異質なものは特別な精査が必要です。設計者が意図しなかった高い権限をさらけ出している可能性があるからです。

これをどのように悪用できるかを理解するために、セキュリティ専門家は GTFOBins というリソースを使用します。GTFOBins は、設定ミスのあるシステムでローカルのセキュリティ制限を回避するために使用できる Unix バイナリのキュレーションリストです。GTFOBins のウェブサイトにアクセスして「find」を検索すると、find には他のコマンドを実行する機能があることがわかります。

私たちの環境にある find バイナリには SUID ビットが設定されているため、それが実行するあらゆるコマンドは、バイナリの所有者(つまり root)の権限で実行されます。

発見を確定させるために、vulnerable_binary.txt というファイルを作成し、悪用可能なバイナリの名前を書き込みます。以下のコマンドを実行してください。

echo "find" > ~/project/vulnerable_binary.txt

ファイルをターミナルに出力して、内容を確認できます。

cat ~/project/vulnerable_binary.txt

出力は単に以下のようになります。

find

この設定ミスを特定したことで、権限昇格攻撃の入り口を見つけたことになります。

エクスプロイトコマンドの作成

このステップでは、find バイナリの SUID 設定ミスを悪用するために必要な具体的なコマンドペイロードを準備します。

GTFOBins によると、find コマンドには -exec パラメータがあります。このパラメータは通常、find が見つけたすべてのファイルに対して特定の操作を実行するために使用されます。しかし、攻撃者はこのパラメータを悪用してシステムシェル(/bin/sh)を実行できます。

標準的なエクスプロイトペイロードは次のようになります:find . -exec /bin/sh -p \; -quit

このペイロードが機能する理由を解説します。. は find に現在のディレクトリから検索を開始するように指示します。-exec フラグは、続くコマンドを実行するように指示します。シェルを起動するために /bin/sh を指定します。-p フラグは非常に重要で、起動時の権限(この場合は SUID ビットによって付与された root 権限)を保持するようにシェルに指示します。\; は実行したいコマンドの終わりを意味します。最後に -quit は、コマンドを一度実行した後に検索を繰り返すのではなく、直ちに終了するように find に指示します。

最終実行の準備として、このエクスプロイトペイロードを exploit.sh という名前のシェルスクリプトファイルに保存しましょう。以下のコマンドを実行してください。

echo 'find . -exec /bin/sh -p \; -quit' > ~/project/exploit.sh

作成したスクリプトを表示して、ペイロードが正しいことを確認します。

cat ~/project/exploit.sh

出力には作成したペイロードが表示されます。

find . -exec /bin/sh -p \; -quit

これで、find バイナリを騙して root シェルを取得するために必要な正確なコマンドが手に入りました。

権限昇格の実行

この最後のステップでは、エクスプロイトを実行し、root ユーザーへの権限昇格に成功したことを証明します。

対話型シェルを直接起動する代わりに(自動化された実験環境では確認が難しいため)、ペイロードを少し修正して、root として単一のコマンドを実行し、その出力を保存します。現在有効なユーザー名を表示する whoami コマンドを使用します。

以下のコマンドを実行して、脆弱な find バイナリ経由で whoami を実行し、出力を root_proof.txt というファイルにリダイレクトします。

/usr/bin/find . -exec whoami \; -quit > ~/project/root_proof.txt

先ほど特定した特定のバイナリを確実に実行するために、絶対パス /usr/bin/find を使用したことに注目してください。find コマンドが実行され、-exec フラグがトリガーされ、SUID ビットのおかげで root 権限で whoami が実行され、その結果が保存されます。

それでは、エクスプロイトが成功したかどうか、証明ファイルの内容を確認しましょう。

cat ~/project/root_proof.txt

エクスプロイトが正しく機能していれば、出力は以下のようになります。

root

おめでとうございます!設定ミスのある SUID バイナリを悪用して、root ユーザーとしてコマンドを実行することに成功しました。

実際にインタラクティブな root シェルを取得する体験をしたい場合は、前のステップで作成したペイロードをターミナルで直接実行できます。

/usr/bin/find . -exec /bin/sh -p \; -quit

コマンドプロンプトが # 記号に変わり、root ユーザーとして操作していることがわかります。exit と入力すれば、root シェルを終了して通常のユーザープロンプトに戻ることができます。

まとめ

この実験では、Linux システムにおける SUID の設定ミスを特定し、悪用する方法を学びました。まず find コマンドを使用して、SUID パーミッションビットが設定されたバイナリを探索しました。/usr/bin/find が異常であることを特定した後、GTFOBins のようなリソースを使用してエクスプロイトペイロードを発見する方法を学びました。最後に、find バイナリの -exec パラメータを悪用するコマンドを作成・実行し、root 権限でコマンドを実行することに成功しました。

この演習は、Linux における適切なパーミッション管理の重要性を浮き彫りにしています。システム管理者は、標準的なユーティリティが意図せず権限昇格の経路を与えてしまわないよう、定期的に SUID バイナリを監査しなければなりません。