setuid ルートが機能しない

setuid ルートが機能しない

目的:プログラム(C ++バイナリ)をrootとして実行します。同じ:UbuntuではSetUIDビットが機能しませんか?

そして:実行可能ファイルに対してsetuidが機能しないのはなぜですか?

./a.out 出力:

E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied) E: Unable to lock the administration directory (/var/lib/dpkg/), are you root? psurana //output for "whoami" Look below for the code.

ls -l 出力:

-rwsrwxr-x 1 root root 46136 Jun 7 20:13 a.out

パスワード:

#include <string>
#include <stdlib.h>
int main(int argc, char *argv[]){
        std::string input = "apt-get install " + std::string(argv[1]);
        system(input.c_str());
        system("whoami");
        return 0;
}

詳細::プログラムをコンパイルして実行しますchown root:root a.out && chmod u+s a.out。上記のls -l出力を参照してください。

まだroot権限がなく、コードのsystem( "whoami")出力はコンピュータの私のユーザー名です。

これら2つの関連する質問を読んでも何も得られませんでした。 :(. ファイルの作成者と所有者は両方とも root です。 setuid ビットが設定されているので動作する必要があります。ファイルシステムも外部ではなく、マイコンピュータです。

答え1

次のようにコードを変更すると、有効な実際のUIDが表示されます。

#include <string>
#include <stdlib.h>
int main(int argc, char *argv[]){
        system("id");
        system("bash -c id");
        return 0;
}

私のシステムでは、次の2行が返されます(関連のないグループをスキップするには...を使用します)。

uid=1001(roaima) gid=1001(roaima) euid=0(root) groups=1001(roaima),24(cdrom),...,103(vboxsf)
uid=1001(roaima) gid=1001(roaima) groups=1001(roaima),24(cdrom),...,103(vboxsf)

ご覧のとおり、元の呼び出しはid有効なUID 0(ルート)を返しますが、実際のUIDはまだ私のものです。これがあなたが期待するものです。

bash -c idただし、呼び出しに有効なUIDが削除され、ルートとして実行されなくなったことがわかります。これはman bash次のように記録されます。

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

したがって、ここで解決策は対応するフラグを含めることです-p

(以下では、bashUIDをリセットするプロセスについて学ぶことができます。setuid ビットは bash に影響を与えないようです。.)

しかし、物語はここで終わりません。なぜなら、あなたが電話していないと言うことを知っているからですbash。残念ながら、それはsystem()あなたに代わって行われるものであり、あなたが指定することを許可しません-p

straceroot権限を放棄しますが、strace -f ./a.out何が起こっているのかを知るのに十分な出力は次のとおりです。

execve("./a.out", ["./a.out"], [/* 44 vars */]) = 0
brk(0)                                  = 0x24f1000
...
clone(child_stack=0, flags=CLONE_PARENT_SETTID|SIGCHLD, parent_tidptr=0x7ffee0d42a1c) = 4619
wait4(4619, Process 4619 attached
 <unfinished ...>

この時点でサブプロセスが開始され、実行準備が完了します。id

[pid  4619] rt_sigaction(SIGINT, {SIG_DFL, [], SA_RESTORER, 0x7f100eb270e0}, NULL, 8) = 0
[pid  4619] rt_sigaction(SIGQUIT, {SIG_DFL, [], SA_RESTORER, 0x7f100eb270e0}, NULL, 8) = 0
[pid  4619] rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
[pid  4619] execve("/bin/sh", ["sh", "-c", "id"], [/* 44 vars */]) = 0
[pid  4619] brk(0)                      = 0x7f849dd71000
[pid  4619] brk(0)                      = 0x7f849dd71000
...
[pid  4619] clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f849d1d89d0) = 4620

これで、有効なUIDを削除するシェルが実行されています。次に、idコマンドを実行して出力を次に記録するのを見ることができます。標準出力あなたのため:

Process 4620 attached
[pid  4619] wait4(-1,  <unfinished ...>
[pid  4620] execve("/usr/bin/id", ["id"], [/* 44 vars */]) = 0
[pid  4620] brk(0)                      = 0x1785000
...
[pid  4620] write(1, "uid=1001(roaima) gid=1001(roaim"..., 149) = 149
uid=1001(roaima) gid=1001(roaima) groups=1001(roaima),24(cdrom),...,103(vboxsf)
...

ここで解決策は、exec*()シリーズの1つを直接使用したり、そのシリーズへの呼び出しを含めたり、たとえばパスワードなしでターゲットプログラムを直接呼び出すことができるsetuid(0)ツールを設定することです。sudo

これらのオプションの中から、私は個人的にsudoソリューションを選択します。この文書の作成者は、(意図しない)特権昇格攻撃からコードが安全であることを確認するために長い時間を費やしました。

答え2

これは2段階のプロセスです。

  1. あなたがしたように実行可能なsuidビットを設定します。

  2. setuid(uid_t uid)フォローするには電話してくださいman setuid

目的がapt-getの場合は、代わりにapt-getを使用できますsudo

関連情報