4

これは実際には3つの部分からなる質問であり、以下で説明しますが、質問は次のとおりです。

  • gdbを使用して、root権限でプログラムの一部を実行し、残りを通常で実行するにはどうすればよいですか?
  • mkstempを使用してsetuid(ルートへ)プログラムの/ tmpにファイルを作成すると、「許可が拒否された」のはなぜですか?
  • 「sudoprogram_name」は、setuidをrootに設定した./program_nameとは異なる動作をするのはなぜですか?

Linux(複数のディストリビューション)で実行されているCプログラムがあり、通常は通常の特権を持つユーザーによって実行されますが、プログラムの一部はroot権限で実行する必要があります。このために、私はset-UIDフラグを使用しましたが、それは問題なく機能します。

しかし、今度は通常のユーザー権限でプログラムをデバッグしたいのですが、キャッチ22があります。一時ファイル(/ tmp / my_name-XXXXXX)を作成する関数を追加しました。この関数は、プログラム内の多くのポイントから呼び出されます。何らかの理由で、この関数は実行時に次のメッセージを発行します。

sh: /tmp/my_name-hhnNuM: Permission denied

(もちろん、実際の名前は異なります。)それでも、プログラムは、root以外のユーザーが実行できないことを私が絶対に知っているrawソケット関数を実行できます。(setuidフラグを削除すると、プログラムは無残に失敗します。)

sudoを使用せずにgdbを介してこのプログラムを実行すると、rawソケットのもので停止します(gdbはプログラムのsetuidフラグを尊重しない、またはおそらくできないため)。「sudogdb」で実行すると、すべて正常に動作します。「sudo./my_name」として実行すると、すべて正常に動作します。

そのプログラムのls-l出力は次のとおりです。

-rwsr-xr-x 1 root root 48222 Jun 23 08:14 my_name

だから私の質問は、順不同です:

  • (どのように)gdbの下で異なる有効なUIDを使用してプログラムの異なる部分を実行できますか?
  • ./programがrootに設定されているのに「sudo./program」が「./program」と異なるのはなぜですか?
  • setuid(rootへの)プログラムで通常のユーザーによって呼び出されたときにmkstempが失敗するのはなぜですか?
4

1 に答える 1

3

1 gdbでsetuidアプリケーションを適切にデバッグする唯一の方法は、gdbをrootとして実行することです。setuidアプリケーションでこれを行う最も賢明な方法は、アプリケーションが起動したらアタッチすることです。これを行うための簡単なトリックは、setuidアプリケーションに行を追加することです。

kill(getpid(), SIGSTOP);

これにより、この時点で停止し、次を使用してgdbをアタッチします。

sudo gdb <application> <pid>

次に、アプリケーションに接続し、通常どおりにデバッグできます。

2 sudoは、現在のユーザーの環境からのさまざまなアイテムをrootユーザーの環境にエクスポートできるようにするため、ルールを変更します。これは現在のsudo構成に完全に依存しており、setuidアプリケーションとは非常に異なる環境を残す可能性があります。そのため、アプリケーションを停止して実行時に接続するなどのトリックに頼る必要があります。

さらに、アプリケーションにsetuid環境で実行されているかどうかを検出するロジックが存在する場合がありますが、sudoで実行した場合は実際にはそうではありません。sudoはすべてのプロセスのidフィールド(実際のuid、有効なuid、保存されたuid)を同じに設定することに注意してください。 setuidにはない値(実際のuidは元の呼び出し元のuidのままです)。getresuid()呼び出しを使用して、3つの変数の状態を判別できます。

3重要なのは、Permission Deniedメッセージのプレフィックスがsh:;であるということです。これは、ファイルにアクセスしようとしている別のサブプロセスが実行されていることを意味しているようです。mkstempを呼び出した後、サブプロセスがファイルを読み取れるように、ファイルを読み取るためのアクセス許可を緩めることができます。

于 2012-06-23T15:53:49.393 に答える