[英]setuid bash script and binfmt_misc credentials flag
在问这个问题时,我不想被告知我不应该这样做或者它不安全。 超出此问题的 scope 的那些事项。
Linux 在使用凭证标志 ( C
) 在 binfmt_misc 文件系统中注册脚本时尊重脚本上的setuid
和setgid
位。 这就是一个证明。 我正在尝试使用相同的工具来制作 shell 脚本,特别是 bash 脚本,这将与setuid
/ setgid
一起使用。 为此,我制作了一个使用文件扩展名匹配的 binfmt 字符串:
:pbash:E::pbash::/bin/bash:C
为了测试这一点,一个名为test.pbash
的文件缺少 shebang 行,由 root 拥有,模式为 6755:
echo "Effective UID: $(id -u)"
echo "Real UID: $(id -ru)"
运行test.pbash
输出:
Effective UID: 1000
Real UID: 1000
有效的 UID 应该显示 0,所以我不得不搜索 web 关于bash
和有效的 UID。 我发现bash
会将有效 UID 更改为真实 UID,除非它在设置-p
标志的情况下运行。 这要求我更改 binfmt 并创建一个包装脚本。
包装脚本, /bin/pbash
,有几个调用-p
以防万一:
#!/bin/bash -p
set -p
exec bash -p -- "$@"
删除旧的 binfmt 并加载新的新 binfmt 字符串:
:pbash:E::pbash::/bin/pbash:C
运行test.pbash
我得到:
Effective UID: 1000
Real UID: 1000
还是行不通。 我想我/bin/pbash
重写为 output 一些信息:
#!/bin/bash -p
set -p
echo "Executing '$0' '$1'" > /tmp/log.txt
exec bash -p -- "$@"
我再次运行test.pbash
并且/tmp/log.txt
不存在,好像/bin/pbash
根本没有运行。 我从 binfmt 字符串中删除了C
标志,再次运行test.pbash
,得到相同的 output。 改变的是/tmp/log.txt
存在:它说:
Executing '/bin/pbash' '/bin/test.pbash'
因此,当我设置了凭据标志时,我的包装脚本甚至都没有运行。 为什么bash
或 Linux 会这样? 如何强制它运行包装脚本?
kernel 文档页面有一个可能很重要的提示:
If you want to pass special arguments to your interpreter, you can
write a wrapper script for it ....
您可能会遇到以下两个问题中的一个或两个:
/bin/bash -p
可能被认为是在寻找一个名为"/bin/bash\ -p"
的文件echo "Effective UID: $(id -u)"
和echo -n "Effective UID: "; id -u
不一样; echo -n "Effective UID: "; id -u
。
$(id -u)
从/bin/bash
的另一个调用中调用id
(可能没有-p
参数)。 我没有深入到一个最小的例子,但这种组合对我有用。 您可能可以将其修剪为更短的内容,但这给出了一个解决上述两个潜在问题的示例:尝试将此代码( pbash.c
)作为解释器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv) {
char **args = calloc(sizeof(char *), argc+2);
memcpy(args+2, argv+1, (argc-1)*sizeof(char *));
args[0] = strdup("bash");
args[1] = strdup("-p");
execv("/bin/bash", args);
perror("exec failed");
}
编译并安装它:
$ gcc -o pbash pbash.c
$ sudo cp pbash /usr/local/bin/
$ ls -l /usr/local/bin/pbash
-rwxr-xr-x. 1 root root 24832 Jul 16 21:35 /usr/local/bin/pbash
$ sudo -s
# echo ':pbash:E::pbash::/usr/local/bin/pbash:C' > /proc/sys/fs/binfmt_misc/register
# exit
$ ls -l /proc/sys/fs/binfmt_misc/
total 0
-rw-r--r--. 1 root root 0 Jul 16 21:29 pbash
--w-------. 1 root root 0 Jul 16 21:29 register
-rw-r--r--. 1 root root 0 Jul 16 20:55 status
并准备一个try.pbash
脚本:
echo -n "Effective UID: " ; id -u
echo -n "Real UID: " ; id -ru
并使其setuid
并运行它:
$ sudo chown root.root try.pbash
$ sudo chmod +xs try.pbash
$ ls -l try.pbash
-rwsr-sr-x. 1 root root 64 Jul 16 21:52 try.pbash
$ ./try.pbash
Effective UID: 0
Real UID: 1000
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.