支持命令执行的常见二进制文件,如“awk”和“vim”,不尊重 setuid 位?

支持命令执行的常见二进制文件,如“awk”和“vim”,不尊重 setuid 位?

我正在强化 Linux 系统,并想使用支持命令执行的常见二进制文件(如、等)测试(setuid基于)shell 转义。awkvim

然而,我测试过的所有二进制文件除外,sh并且bash不尊重他们的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)

相反,当给定选项时bash执行:root-p

$ 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

操作系统

# 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

$ 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)

在您的示例中,不是awk删除权限或不“尊重其 setuid 位”,而是/bin/shawk 用于实现其system()功能的命令。

就像它的 C 版本一样,awksystem()不直接解析和运行命令,而是将其作为参数传递给/bin/sh -c.如果/bin/sh是 bash(或 Debian 版本的 dash,或从 bash 复制此错误功能的其他几个 shell),它会将其有效 uid 重置回真实的 uid。

同样的事情也适用于awkprint | "cmd""cmd" | getlineawk 中——它们是通过popen(3)which调用来实现的/bin/sh -c。请注意,它始终是/bin/sh(或系统的 shell,例如/system/bin/sh在 Android 上),而不是用户的登录 shell 或来自$SHELL环境变量的 shell。[1]

这在 perl 中有所不同:perl 的systemexecopen "|-"open2open3等如果使用多个参数调用或者命令不包含 shell 元字符,则将直接运行该命令:

$ 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

这个示例是在 Debian 10 上进行的。在 FreeBSD 或旧版 Debian 等其他系统上,这两个命令将打印相同的内容,因为它们/bin/sh不会删除权限。[2]


笔记:

[1]其他程序喜欢vimless确实使用$SHELL环境变量,因此可以通过将其指向某个包装器来轻松“修复”它们。您vim还可以使用:set shcf=-pc将选项传递给用于类似命令-p的 shell 。:!

[2]perl 示例也可以像在 FreeBSD 上一样在 OpenBSD 上运行,只要您将 替换env - /tmp/perl 'script'为更钝的echo 'script' | /tmp/perl /dev/fd/0.

当在 setuid 模式下运行时,OpenBSD 的 perl 将拒绝该-e参数并拒绝从 stdin 读取其脚本(请参阅正在结束这里-- 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

相关内容