web-dev-qa-db-ja.com

setuidビットを尊重しない「awk」や「vim」などのコマンド実行をサポートする一般的なバイナリ?

Linuxシステムを強化していて、コマンドの実行をサポートするsetuidawkなどの一般的なバイナリを使用して(vimベースの)シェルエスケープをテストしたいと思いました。

ただし、shbashを除いて、私がテストしたすべてのバイナリは、それらのsetuidビットを尊重しません。

特に、awkは通常のユーザーとして実行を継続します。

$ ls -lL /usr/bin/awk
-rwsr-xr-x 1 root root 121976 Mar 23  2012 /usr/bin/awk
$ id
uid=1000(bob) gid=1000(bob) groups=1000(bob)
$ awk 'BEGIN{system("id")}'
uid=1000(bob) gid=1000(bob) groups=1000(bob)

対照的に、-pオプションを指定すると、bashrootとして実行されます。

$ ls -la /bin/bash
-rwsr-xr-x 1 root root 1168776 Apr 18  2019 /bin/bash
$ /bin/bash -p
# id
uid=1000(bob) gid=1000(bob) euid=0(root) groups=1000(bob)

awkvimlessなどにsetuidビットを尊重させ、コマンドをrootとして実行する方法はありますか?

[〜#〜] os [〜#〜]

# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

更新

parallels@debian-gnu-linux-vm:~$ ls -la /proc/self/fd/0 /dev/fd/0 /dev/stdin
lrwx------ 1 parallels parallels 64 Mar 26 08:15 /dev/fd/0 -> /dev/pts/1
lrwxrwxrwx 1 root      root      15 Mar 20 19:56 /dev/stdin -> /proc/self/fd/0
lrwx------ 1 parallels parallels 64 Mar 26 08:15 /proc/self/fd/0 -> /dev/pts/1
1
Shuzheng
$ ls -lL /usr/bin/awk
-rwsr-xr-x 1 root root 121976 Mar 23  2012 /usr/bin/awk
$ awk 'BEGIN{system("id")}'
uid=1000(bob) gid=1000(bob) groups=1000(bob)

あなたの例では、特権を落としたり「setuidビットを尊重」したりするのはawkではなく、awkがsystem()関数を実装するために使用する/bin/shコマンドです。

Cの対応物と同様に、awkのsystem()はコマンドを直接解析して実行するのではなく、引数として/bin/sh -cに渡します。 /bin/shがbash(または、Debianバージョンのdash、またはこの誤った機能をbashからコピーした他のいくつかのシェル)の場合、有効なuidを実際のuidにリセットします。

同じことがawkのprint | "cmd"または"cmd" | getlineにも当てはまります。これらは/bin/sh -cを呼び出すpopen(3)で実装されています。これは常に/bin/sh(またはシステムのシェル(Androidでは/system/bin/shなど))であり、ユーザーのログインシェルや$Shell環境変数からのものではないことに注意してください。 [1]

これはPerlでは異なります。Perlのsystemexecopen "|-"open2open3などは、複数の引数で呼び出された場合、またはコマンドにシェルメタ文字が含まれていない場合、コマンドを直接実行します。 :

$ id -nu
ahq
$ ls -l /tmp/Perl
-rwsr-xr-x 1 dummy_user dummy_user 3197768 Mar 24 18:13 /tmp/Perl
$ env - /tmp/Perl -e 'system("id -nu")'
dummy_user
$ env - /tmp/Perl -e 'system("{ id -nu; }")'
ahq

この例はDebian10上にあります。FreeBSDや古いDebianのような他のシステムでは、/bin/shが特権をドロップしないため、両方のコマンドは同じものを出力します。 [2]


注:

[1]vimlessのような他のプログラムは、$Shell環境変数を使用するので、簡単に「ラッパーを指すことで修正可能」。 vimでは、:set shcf=-pcを使用して、-pおよび同様のコマンドに使用されるシェルに:!オプションを渡すこともできます。

[2]Perlの例は、env - /tmp/Perl 'script'をより鈍いecho 'script' | /tmp/Perl /dev/fd/0に置き換えると、FreeBSDと同じようにOpenBSDでも機能します。

OpenBSDのPerlは、setuidモードで実行しているときに、-e引数を拒否し、stdinからのスクリプトの読み取りを拒否します( this 終了を参照 here -OpenBSDにはおそらく安全なsetuidスクリプトがあります)。

しかし、それは/dev/fd/Nには当てはまりません。Perlは それ自体を処理します スクリプト名として指定された場合(/dev/fd/Nまたは/dev/stdinではなく/proc/self/fd/Nフォームのみ)。

obsd66$ ls -l /tmp/Perl
-rwsr-xr-x  1 dummy_user  dummy_user  10728 Mar 25 18:34 /tmp/Perl

obsd66$ env - /tmp/Perl -e 'system("{ id -nu; }")'
No -e allowed while running setuid.

obsd66$ echo 'system("{ id -nu; }")' | env - /tmp/Perl
No program input from stdin allowed while running setuid.

obsd66$ echo 'system("{ id -nu; }")' | env - /tmp/Perl /dev/stdin
Can't open Perl script "/dev/stdin": Operation not permitted

obsd66$ echo 'system("{ id -nu; }")' | env - /tmp/Perl /dev/fd/0
dummy_user
debian10$ su - other_user -c 'Perl /dev/fd/7' 7<<<'print "OK\n"'
OK
debian10$ su - other_user -c 'Perl /proc/self/fd/7' 7<<<'print "OK\n"'
Can't open Perl script "/proc/self/fd/7": Permission denied
7
mosvy