2

C で実行しているプログラムがあります。これには、system を使用して「iptables」コマンドを実行する必要があります。

私は試した

setuid(0); 
system("iptables .... ");

setuid と system は共存しません。システムのマニュアルページから

set-user-ID または set-group-ID 特権を持つプログラムから system() を使用しないでください。一部の環境変数の奇妙な値がシステムの整合性を破壊するために使用される可能性があるためです。代わりに exec(3) ファミリの関数を使用してください。ただし、execlp(3) または execvp(3) は使用しないでください。実際、system() は、/bin/sh が bash バージョン 2 であるシステムでは、set-user-ID または set-group-ID 権限を持つプログラムからは正しく機能しません。これは、bash 2 が起動時に権限を失うためです。(Debian は、sh として呼び出されたときにこれを行わない、変更された bash を使用します。)

どうすれば自分の問題を克服できますか?

ありがとう

4

3 に答える 3

4

system() は setuid() と連携して動作しますが、それが問題です: 重大なセキュリティ リスクです。問題は、system() がどのような環境でもシェル (bash、sh など) を開始することです。「iptables」を実行する場合、私の PATH は、簡単に使用できる独自のバージョンの iptables を指す可能性があります。ルートとして、私のために走るよう説得してください。iptables へのフル パスを使用することで解決できるように見えますが、他の環境変数 (LD_PRELOAD_PATH など) を使用して、不正な共有ライブラリをツールにロードさせることができます。

安全に行う必要があることについては、exec() ファミリーのいずれかを使用する必要があり、その動作環境を制御する必要があります。それ以外は、セキュリティの悪用を求めています。http://pubs.opengroup.org/onlinepubs/009695399/functions/environ.htmlは、詳細を学ぶのに適した場所のようです。

于 2011-06-07T16:56:40.103 に答える
2

を使用する必要があるのはなぜsystem()ですか? man ページには、何をすべきかが正確に示されています。

exec(3)代わりに関数ファミリを使用しますが、 execlp(3)orは使用しませんexecvp(3)

fork(2)およびwait(2)システム コールにも関心があるでしょう。

于 2011-06-07T16:49:41.377 に答える
1

このようなものが役立つかもしれません。テストされていませんが、動作するはずです。

    char * const argv[] = {"/sbin/iptables", "-L", NULL};

    pid = fork();
    switch (pid) {
            case -1:
                    /* handle error */
            case 0:
                    execv("/sbin/iptables", argv);
                    /* handle error if you get here */
            break;
            default:
                    waitpid(pid, &status, 0);
                    /* check waitpid return code */
            break;
    }
于 2011-06-07T17:05:10.203 に答える