我需要运行bash脚本,作为root(无密码须藤或SU不可行),因为你可以没有被setuid在Linux中的脚本,我想到了从一个可执行文件调用它,使的的setuid的:

$ cat wrapper.c
int main(void)
{
        system("/bin/bash ./should_run_as_root.sh");
}
$ gcc -o wrapper wrapper.c
$ sudo chown root wrapper
$ sudo chmod ug+s wrapper
$ ll wrapper
-rwsr-sr-x 1 root users 6667 2009-02-17 11:11 wrapper
$

这工作 - 在正常运行的脚本 - 但脚本运行作为谁执行“./wrapper”用户

为什么呢?而如何正确地实现这一点?

谢谢!

有帮助吗?

解决方案

由于上可执行的suid比特仅改变有效UID(EUID)的可执行文件将作为运行,而不是真正的UID(RUID),其getuid()回报,除了上suid解释脚本中的限制(任何可执行开始与“#!”),像bash作为额外的安全措施将设置EUID回RUID在这种情况下,一些炮弹,你将需要执行该脚本前使用的C代码调用setuid(0)

请参阅所述mansetuidseteuid,和getuidgeteuid页了解真实有效的UID的确切语义。

警告)当然,这是一个适当的点一提的是在许多Unix系统,贝壳和口译suid脚本的限制,是有原因的,这是,如果脚本是不是很小心消毒的输入,则在执行时环境的状态,他们是危险的,可被利用的安全升级。因此,执行此操作时要非常小心。设置访问您的脚本和包装严格,你可以只允许你打算执行这个非常具体的脚本,并启动脚本之前清除你的C程序中的环境,设置环境变量,例如PATH含有什么是按照正确的顺序且没有目录,可写他人必要的。

其他提示

这里要注意的另一件事是,这里的限制是从bash和不是的* nix系统本身。巴什实际上就SUID脚本验证只与EUID根执行。如果你把旧的炮弹,你经常会得到你想要的开箱即用的东西。例如,SH不会使这种核查:

$ cat wrapper.c
int main(void)
{
            system("/bin/sh -c whoami");
}

$ ls -l wrapper
-rwsr-sr-x 1 root users 8887 Feb 17 14:15 wrapper
$ ./wrapper
root

通过bash中:

$ cat wrapper.c
int main(void)
{
            system("/bin/bash -c whoami");
}

$ ls -l wrapper
-rwsr-sr-x 1 root users 8887 Feb 17 14:18 wrapper
$ ./wrapper
skinp

不过,汤姆的回答通常是去制作的包装为SUID根程序的方式

(0)在脚本添加setuid和编译。应该在此之后工作。

$ cat wrapper.c 
int main(void) 
{ 
        setuid(0);
        system("/bin/bash ./should_run_as_root.sh"); 
} 
$ gcc -o wrapper wrapper.c 
$ sudo chown root wrapper 
$ sudo chmod ug+s wrapper 
$ ll wrapper 
-rwsr-sr-x 1 root users 6667 2009-02-17 11:11 wrapper 
$ 

在实例是可怕的不安全的,并允许任何有知识的两个比特来运行他们想要作为用户的setuid任何程序。

从不通过壳去除非首先消毒环境中,大多数的这里示出的例子是易受具有IFS和PATH运行它之前设置。

为什么须藤不是可行?它避免了汹涌的安全漏洞,例如:

bash-3.2$ cat test
#!/bin/bash
echo ima shell script durp durp
bash-3.2$ chmod +x test
bash-3.2$ ./test
heh heh
bash-3.2$ 

由于环境没有被正确过滤,例如在这种情况下:

export echo='() { builtin echo heh heh; }'

须藤进行消毒这种情况下,可能还有其他边缘情况和陷阱,这将是很好不写到定制SUID包装。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top