setuidビットが一貫して動作しないのはなぜですか?

setuidビットが一貫して動作しないのはなぜですか?

私はコードを書いた:

// a.c
#include <stdlib.h>
int main () {
  system("/bin/sh");
  return 0;
}

次のコマンドを使用してコンパイルします。

gcc a.c -o a.out

setuidビットを追加しました:

sudo chown root.root a.out
sudo chmod 4755 a.out

Ubuntu 14.04では、通常のユーザーとして実行するとroot権限が得られます。

しかし、Ubuntu 16.04ではまだ現在のユーザーのシェルを取得します。

なぜ違うの?

ベストアンサー1

変更されたことは、/bin/shbebashまたはstay bashの動作を模倣するdash追加のフラグがあることです。-p

-pBashでは、次の説明に従ってsetuid権限を放棄しないためにこのフラグが必要です。マニュアルページ:

シェルの起動時に有効なユーザー(グループ)IDが実際のユーザー(グループ)IDと同じでなく、-pオプションが指定されていない場合は起動ファイルを読み取らず、シェル機能は環境とSHELLOPTS、BASHOPTS、CDPATH、およびGLOBIGNORE変数が表示された場合は無視します。になります。有効ユーザーIDを実際のユーザーIDに設定します。。呼び出し時に-pオプションを指定した場合、起動動作は同じですが、有効なユーザーIDはリセットされません。

以前はdashこれは無視され、setuidの実行は許可されました(これを防ぐための措置は取られていませんでした)。しかし、Ubuntu 16.04dashマンページ次のような追加オプションの説明がありますbash

-p priv
有効な uid が uid と一致しない場合はリセットしないでください。誤った使用を防ぐためにデフォルトでは設定されていません。system(3) または popen(3) を介した Setuid ルートプログラム。

このオプションは、次には存在しません。上流(提案されたパッチに反応しないことがあります。*)もDebian 9ではありませんが、2018年からパッチされたDebian Busterにあります。

"/bin/sh -p"注:Stéphane Chazelasが説明したように、特定のコンテンツが実行されるため、system()今すぐ電話するのは遅すぎます。したがって、setuidはすでに削除されています。system()/bin/shドロバート前のコードの答えは、この問題を処理する方法を説明していますsystem()

*歴史の詳細ここそしてそこ

おすすめ記事