问题描述
我正在尝试编写一个以用户 smith 权限运行 /bin/bash 的程序,
smith:x:1000:1000:Basket:/home/smith:/bin/bash
我试过了:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
setgid(1000);
setuid(1000);
char command[50];
strcpy( command,"/bin/bash" );
system(command);
return(0);
}
我使用这些命令来设置所有者、组和权限
chown smith command
chgrp smith command
chmod +x command
chmod u+s command
命令后的权限:
-rwsr-xr-x 1 smith smith 16840 Jun 6 17:11 command
并没有工作,我尝试使用 root 作为下一个:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
setgid(0);
setuid(0);
char command[50];
strcpy( command,"/bin/bash" );
system(command);
return(0);
}
我使用相同的命令来获取权限等等,但我没有写 smith,而是写了 root 并且我工作了,当我运行它时,我以 root 身份获得了一个 shell。
那么我如何与 smith 用户一起做呢?
解决方法
Linux 就是这样工作的 (tm)
如果任何用户都可以随意变成另一个用户,那么 Linux 将完全没有访问权限。
只有以 root 权限运行的进程才能更改其有效凭据。
话虽如此,Linux 提供了细粒度的凭据。见:
$ man 7 capabilities
了解详情。
解决“我想成为 root”综合症的更好方法是查看 sudo(8)。使用 sudo(8) 更好,因为:
- 您可以控制谁拥有权力。
- 您可以控制用户可以运行哪些应用程序。
- 您甚至可以强制要求他们必须提供的前几个命令行操作。
- 在审计跟踪中记录了一个条目,因此您知道当机器崩溃时应该归咎于谁。
我使用这些命令来设置所有者、组和权限
chown smith command
chgrp smith command
chmod +x command
chmod u+s command
如果您在程序模式下使用 SUID 和/或 SGID 位,则程序不需要调用相应的身份更改函数。系统将自动运行具有所有者 (SUID) 和/或组 (SGID) 身份的程序。因此,如果您使用这种方法在 root 以外的 uid 下运行,则程序不得尝试调用身份更改函数,因为只有以足够权限运行的程序才能这样做。
因此,您的主要(互斥)选项如下:
-
使用可执行文件的所有权和模式(SUID / SGID 位)来选择程序运行的非特权身份,并避免调用
setuid()
或setgid()
。任何对该程序具有执行权限的用户都将作为指定的用户/组执行它。 -
在运行时使用
setuid()
和/或setgid()
函数设置程序运行的身份。如果程序由非特权用户运行,这些功能将失败。 -
在 Linux 下,使用功能子系统授予可执行文件更改其用户身份的权限。 (细节不仅仅是另一个完整的答案。)
-
根本不要这样做。这可能是您最好的选择。 Setuid 程序有风险,setuid shell 脚本风险更大,我认识的任何安全专家都不会接受像您这样的程序,它试图允许任意用户以不同身份运行任意 shell 命令。