
私は別のユーザーとして、C++ でコンパイルされたプログラムを root として実行しようとしています。
プログラムは正常に実行されますが、ルートではなく通常のユーザーとして実行されます。
しかし、インターネットで言われているように、chmod u+s
コマンドは所有者(私の場合は root)として実行されます。
プログラムは単純なsystem(argv[1])
行であり、コマンドライン引数内のすべてを実行します。
たとえば、出力はwhoami
ルートではなく自分のユーザーを返します。
また、内容を一覧表示しようとすると、/root
「アクセスが拒否されました」というエラーが表示されます。
ファイルの権限 -
-rwsr-xr-x 1 root root 16608 Aug 25 15:20 test
この時点で、ファイルの権限を作成しようとしました4755
(うまくいきませんでした)。
ファイルの移動/root
もうまくいきませんでした。
答え1
system() 呼び出しは、execl()
システム コールを使用して新しいシェル プロセスを作成します。ただし、システム コールは有効なユーザー ID を無視し、EPERM エラー (権限が拒否されました) を返します。
これは Linux シェルが seteuid ビットを継承しないためです。なぜでしょうか? 実効ユーザー ID を root としてスクリプトを実行することには大きな懸念があるからです。このトピックの詳細については、以下を参照してください。ここ。
パラメータを渡すことで、実効 UID に基づいて動作するシェルを実行することができます。マニュアル ページ-p
から引用:sh
-p 特権 実効 uid が uid と一致しない場合は、実効 uid をリセットしないでください。これは、system(3) または popen(3) を介して setuid ルート プログラムによる誤った使用を回避するために、デフォルトでは設定されていません。
もちろん、この制限はシステム コールには適用されません。デモとして、この C プログラムは を使用して /root の一覧表示を試みsystem()
、次にopendir()
およびreaddir()
システム コールを使用して同じことを行います。
バイナリが、設定されたユーザー ID を持つ root によって所有されている場合、非 root ユーザーがプログラムを実行すると、最初の /root リストは失敗し、2 番目 (を使用) は機能しdisplay_dir()
ます。
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<dirent.h>
#include<errno.h>
int display_dir(const char *dirname)
{
DIR *dp = opendir(dirname);
struct dirent *sd=NULL;
if (!dp) return(errno);
while ((sd = readdir(dp)) != NULL)
{
printf("%s\n", sd->d_name);
}
closedir(dp);
return 0;
}
int main()
{
system("ls /root");
printf("Display returned %d\n", display_dir("/root"));
}