いくつかのCTF課題を実装しています。これらのフラグは、プログラムによって読み取られるいくつかのテキストファイルにあります。フラグを保護するためにファイルの所有者を変更しましたが、setuid
ファイルを読み取ることができるように実行可能にしました。 gdbの外部でプログラムを実行すると、動作するフラグを読み取ることができますが、gdbの内部ではPermission denied
VirtualBoxのLinux仮想マシンで練習を実行しています。 sudoersファイルにない一般ユーザーを作成し、フラグファイルはrootに属します。
-rwsr-xr-x 1 root user 15260 Mar 13 13:22 exercise6
-rw-r--r-- 1 user user 3270 Mar 13 06:10 'Exercise 6.c'
-rwsr-xr-x 1 root user 15700 Mar 14 03:28 exercise7
-rw-r--r-- 1 user user 4372 Mar 13 06:10 'Exercise 7.c'
-rwS------ 1 root root 28 Mar 13 06:10 admin_flag.txt
-rwS------ 1 root root 20 Mar 13 06:24 exercise1.txt
-rwS------ 1 root root 27 Mar 13 06:24 exercise2.txt
-rws------ 1 root user 18 Mar 13 10:34 exercise3.txt
-rwS------ 1 root root 22 Mar 13 06:24 exercise4.txt
-rwS------ 1 root root 19 Mar 13 06:10 user_flag.txt
答え1
setuid1のセキュリティ契約は、実行プログラムに追加の権限を付与することです。これらの権限はこのプログラムにのみ付与されます。呼び出し側のユーザーがプログラムが実行しない操作を実行できるようにしないでください。
これにより、setuidはトレース(ptrace
ほとんどのUnixバリアントではシステムコール)と互換性がありません。呼び出しユーザーがプログラムの内部操作を観察できる場合は、プログラムがアクセスできるすべての機密データにアクセスできます。ただし、これはユーザーが見ることができない機密データである可能性があり、プログラムは通常このデータを公開しません。おそらくもっと明確に言えば、呼び出し側のユーザーがプログラムが実行する操作を変更できる場合(可能であればptrace
)、setuidユーザーのすべての権限へのフルアクセスを許可し、1つの特定のプログラムのみを実行する権限与えようとする目標を完全に崩すことです。トレースは、プログラムの実行をチェックして制御するためにGDBなどのデバッガが使用する機能です。
unix_chkpwd
たとえば、呼び出し元のユーザーのパスワードを確認するタスクを実行するプログラムを考えてみましょう。プログラムは機密データ(パスワードハッシュデータベース)を読み取ることができなければなりません。ただし、呼び出し側のユーザーはデータベース全体を読み取ることはできません。呼び出し側のユーザーは、そのユーザーのエントリを照会し、はい/いいえでのみ答えることができ、パスワードハッシュ自体を抽出せずに無差別代入攻撃を防ぐための制限が必要です。パスワードハッシュデータベースの内容を実行して印刷できる場合、gdb unix_chkpwd
そのデータベースのセキュリティは完全に崩壊します。
セキュリティを維持するには:
- プログラムが起動時にすでに追跡されている場合、setuidビットは無視されます。実行可能ファイルは追加の権限なしで起動されます。
- 追加の権限で開始されたプログラムのルート追跡のみを許可します。
1これは、昇格された権限でプログラムを実行するためのsetgid、setcap、または他の同様のメカニズムにも適用されます。