web-dev-qa-db-ja.com

setuidルートCプログラムからスクリプトを呼び出す-スクリプトがルートとして実行されない

Rootとしてbashスクリプトを実行する必要があります(パスワードなしのSudoまたはsuは実行不可)。Linuxではスクリプトをsetuidできないため、実行可能ファイルからスクリプトを呼び出してit setuidにすることを考えました:

$ cat wrapper.c
int main(void)
{
        system("/bin/bash ./should_run_as_root.sh");
}
$ gcc -o wrapper wrapper.c
$ Sudo chown root wrapper
$ Sudo chmod ug+s wrapper
$ ll wrapper
-rwsr-sr-x 1 root users 6667 2009-02-17 11:11 wrapper
$

これは、スクリプトを正しく実行する場合と同様に機能しますが、スクリプトは「./wrapper」を実行するユーザーとして実行されます。

どうして?そして、これを正しく実装する方法は?

ありがとう!

25
Jack

実行可能ファイルのsuidビットは、実行可能ファイルが実行される有効なUID(EUID)のみを変更するため、getuid()が返す実際のUID(RUID)ではなく、suid解釈スクリプトの制限に加えて、 "_#!_"で始まる実行可能ファイル)、追加の安全対策としてbashなどの一部のシェルは、この場合EUIDをRUIDに設定します。Cでsetuid(0)を呼び出す必要があります。スクリプトを実行する前のコード。

実際の実効UIDの正確なセマンティクスについては、mansetuidseteuidgetuidgeteuidページをご覧ください。

[〜#〜] warning [〜#〜])もちろん、これは、多くのUnixシステム、シェル、インタプリタにおけるsuidスクリプトの制限が理由のために存在することを言及するのに適切なポイントですこれは、スクリプトが実行時の入力と環境の状態のサニタイズについて細心の注意を払っていない場合、それらは危険であり、セキュリティのエスカレーションに悪用される可能性があるということです。したがって、これを行うときは十分注意してください。スクリプトとラッパーへのアクセスをできる限り厳密に設定し、実行する予定のこの非常に特定のスクリプトのみを許可し、スクリプトを開始する前にCプログラム内の環境をクリアし、PATHなどの環境変数を設定して、正しい順序で必要であり、他のユーザーが書き込み可能なディレクトリはありません。

42
Tom Alsberg

ここで注意すべきもう1つの点は、ここでの制限は* nixシステム自体ではなく、bashからのものであることです。 Bashは実際にはSUIDスクリプトを検証して、EUIDルートでのみ実行します。古いシェルを使用すると、たいていの場合、必要なものがすぐに使用できるようになります。たとえば、shはこの種の検証を行いません。

$ cat wrapper.c
int main(void)
{
            system("/bin/sh -c whoami");
}

$ ls -l wrapper
-rwsr-sr-x 1 root users 8887 Feb 17 14:15 wrapper
$ ./wrapper
root

Bashの場合:

$ cat wrapper.c
int main(void)
{
            system("/bin/bash -c whoami");
}

$ ls -l wrapper
-rwsr-sr-x 1 root users 8887 Feb 17 14:18 wrapper
$ ./wrapper
skinp

それでも、トムの答えは一般的にSUIDルートプログラムのラッパーを作成する方法です

7
skinp

スクリプトにsetuid(0)を追加してコンパイルします。これでうまくいくはずです。

$ cat wrapper.c 
int main(void) 
{ 
        setuid(0);
        system("/bin/bash ./should_run_as_root.sh"); 
} 
$ gcc -o wrapper wrapper.c 
$ Sudo chown root wrapper 
$ Sudo chmod ug+s wrapper 
$ ll wrapper 
-rwsr-sr-x 1 root users 6667 2009-02-17 11:11 wrapper 
$ 
3
Novice scripter

これらの例は恐ろしく安全ではなく、2つの知識を持っている人なら誰でも、setuidユーザーとして必要なプログラムを実行できます。

最初に環境をサニタイズしない限りシェルを経由しないでください。ここに示す例のほとんどは、実行する前にIFSとPATHを設定することに対して脆弱です。

1
Henrik

Sudoが実行できないのはなぜですか?これは、次のような激しいセキュリティホールを回避します。

bash-3.2$ cat test
#!/bin/bash
echo ima Shell script durp durp
bash-3.2$ chmod +x test
bash-3.2$ ./test
heh heh
bash-3.2$ 

この場合のように、環境が適切にサニタイズされていないため:

export echo='() { builtin echo heh heh; }'

Sudoは、このケース、そしておそらく他のEdgeケースとカスタムのsuidラッパーに書き込むのはよくないだろうことをサニタイズします。

0
user1028793