web-dev-qa-db-ja.com

バイナリファイルのSUIDビットにより、依然として「アクセス許可が拒否されました」エラーが発生する

alicebobはどちらもstaffグループに属しています。

次のフォルダがあります。

_drwxrwxr-x 2 alice staff 4096 Oct 30 14:45 share_

フォルダ内に次のファイルが含まれています。

_-rwsr-xr-x 1 alice alice 8768 Oct 30 14:45 display-foo
-rw------- 1 alice alice 24 Oct 30 14:45 foo.txt
_

_display-foo_はバイナリファイルであり、catコマンドを使用して_foo.txt_の内容を本質的に表示します。

aliceが_./display-foo_を実行すると、バイナリファイルが正常に実行され、_foo.txt_の内容が表示されます。ただし、bobが_./display-foo_を実行すると、バイナリファイルは正常に実行されますが、_foo.txt_の内容は表示されないであり、エラー_/bin/cat: /home/alice/share/foo.txt: Permission denied_が発生します。


私の理解では、setuidビットを設定すると、バイナリ実行可能ファイルをファイルの所有者(この場合はalice)の特権で実行できます。それでは、_bobが_foo.txt_の内容を表示することを許可されなかったのはなぜですか?


[〜#〜] addendum [〜#〜]binaryファイルをgeteuid()関数で再コンパイルして、有効なユーザーを出力するようにしましたID(EUID)。実際、bobがバイナリファイルを実行すると、EUIDはaliceのEUIDになります。しかし、許可は拒否されました。ソースコードのスニペットを次に示します。

_printf("%d", geteuid());
system("/bin/cat /home/alice/share/foo.txt");
_
6
JTJM

system関数の manual page を読み、説明を提供する次の文章に出くわしました。

Do not use system() from a program with set-user-ID or set-group-ID
privileges, because strange values for some environment variables
might be used to subvert system integrity.  Use the exec(3) family of
functions instead, but not execlp(3) or execvp(3).  system() will
not, in fact, work properly from programs with set-user-ID or set-
group-ID privileges on systems on which /bin/sh is bash version 2,
since bash 2 drops privileges on startup.  (Debian uses a modified
bash which does not do this when invoked as sh.)

以下は、その一節に行く途中で読んだStackExchangeの他の投稿です。

後世のために、そして与えられた例は他の状況でこれまたは同様の問題を診断するのに役立つかもしれないので、私は以下のオリジナルを維持しました。


バグが発生している可能性はありますか? Debian 9とgcc 6.3を実行しているDockerコンテナーで問題を再現できませんでした。これが私があなたの投稿で説明されたシナリオを再現しようと試みた方法です。

最初に「alice」と「bob」のユーザーを作成し、それらを「staff」グループに追加します。

useradd -m -G staff alice
useradd -m -G staff bob

次に、ファイルを作成し、その所有権と権限を設定します。

# Create a subdirectory to hold the text file
Sudo -u alice mkdir -p /home/alice/share/

# Create the text file
Sudo -u alice bash -c 'echo "This is foo.txt" > /home/alice/share/foo.txt'

# Set restrictive permissions on the text file
chmod u=rw,g=,o= /home/alice/share/foo.txt

結果を確認してみましょう:

$ ls -l /home/alice/share/foo.txt
-rw------- 1 alice alice 16 Nov  4 15:33 /home/alice/share/foo.txt

次に、system関数を使用するdisplay-fooのバージョンを作成します。

$ cat <<HEREDOC > /usr/local/src/display-foo.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>

int main(int argc, char **argv) {

    struct passwd *r_pwd = getpwuid(getuid());
    printf("Real user: %s\n", r_pwd->pw_name);

    struct passwd *e_pwd = getpwuid(geteuid());
    printf("Effective user: %s\n", e_pwd->pw_name);

    system("/bin/cat /home/alice/share/foo.txt");
}
HEREDOC

$ gcc /usr/local/src/display-foo.c -o /usr/local/bin/display-foo

そして、setuidビットの設定を含め、display-fooの所有権と権限を設定しましょう。

chown alice:alice /usr/local/bin/display-foo
chmod u=rwx,g=rx,o=rx /usr/local/bin/display-foo
chmod u+s /usr/local/bin/display-foo

結果も確認してみましょう:

$ ls -l /usr/local/bin/display-foo
-rwsr-xr-x 1 alice alice 8640 Nov  4 15:40 /usr/local/bin/display-foo

次に、プログラムをalicebobの両方として実行します。

$ Sudo -u alice display-foo

Real user: alice
Effective user: alice
This is foo.txt

$ Sudo -u bob display-foo

Real user: bob
Effective user: alice
This is foo.txt

ご覧のとおり、すべてが期待どおりに機能しているようです。

1
igal

foo.txtファイルはAlice home directoryの共有ディレクトリにあるため、権限が原因でボブはAlice home directoryのファイルにアクセスできません。ホームにshared directoryを作成し、このディレクトリにアクセスするための両方の権限を与えることができます。

または、groupownerの譜表でshared directoryを作成し、次のコマンドでSGIDビットを設定できます。

chmod 2777 sharedDir

SGIDビットがディレクトリに設定されている場合、元のディレクトリに作成された新しいファイルまたはサブディレクトリは、ユーザーの現在のデフォルトグループではなく、ディレクトリのグループ所有権を継承します。

したがって、ここでAliceファイルを作成すると、ファイルのグループ所有権は[〜#〜] staff [〜#〜]になり、このグループのすべてのメンバーがこれらのファイルにアクセスできますstaffグループ権限に基づいています。

0
anis