我正在强化 Linux 系统,并想使用支持命令执行的常见二进制文件(如、等)测试(setuid
基于)shell 转义。awk
vim
然而,我测试过的所有二进制文件除外,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)
有没有办法让awk
、vim
、less
等尊重该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/sh
awk 用于实现其system()
功能的命令。
就像它的 C 版本一样,awksystem()
不直接解析和运行命令,而是将其作为参数传递给/bin/sh -c
.如果/bin/sh
是 bash(或 Debian 版本的 dash,或从 bash 复制此错误功能的其他几个 shell),它会将其有效 uid 重置回真实的 uid。
同样的事情也适用于awkprint | "cmd"
或"cmd" | getline
awk 中——它们是通过popen(3)
which调用来实现的/bin/sh -c
。请注意,它始终是/bin/sh
(或系统的 shell,例如/system/bin/sh
在 Android 上),而不是用户的登录 shell 或来自$SHELL
环境变量的 shell。[1]
这在 perl 中有所不同:perl 的system
、exec
、open "|-"
、open2
、open3
等如果使用多个参数调用或者命令不包含 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]其他程序喜欢vim
并less
确实使用$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