7

我编写了一个小型 C 实用程序,调用killSPR它来杀死我的 RHEL 机器上的以下进程。这个想法是让任何登录到这个 linux 框的人都能够使用这个实用程序来杀死下面提到的进程(这不起作用 - 下文解释)。

cadmn@rhel /tmp > ps -eaf | grep -v grep | grep " SPR "  
cadmn    5822  5821 99 17:19 ?        00:33:13 SPR 4 cadmn  
cadmn   10466 10465 99 17:25 ?        00:26:34 SPR 4 cadmn  
cadmn   13431 13430 99 17:32 ?        00:19:55 SPR 4 cadmn  
cadmn   17320 17319 99 17:39 ?        00:13:04 SPR 4 cadmn  
cadmn   20589 20588 99 16:50 ?        01:01:30 SPR 4 cadmn  
cadmn   22084 22083 99 17:45 ?        00:06:34 SPR 4 cadmn  
cadmn@rhel /tmp >  

该实用程序归用户所有cadmn(这些进程在其下运行),并在其上设置了 setuid 标志(如下所示)。

cadmn@rhel /tmp > ls -l killSPR  
-rwsr-xr-x 1 cadmn cusers 9925 Dec 17 17:51 killSPR  
cadmn@rhel /tmp > 

C代码如下:

/*  
 * Program Name: killSPR.c  
 * Description: A simple program that kills all SPR processes that  
 * run as user cadmn  
 */  
#include <stdio.h>  
int main()  
{  
    char *input;  
    printf("Before you proceed, find out under which ID I'm running. Hit enter when you are done...");  
    fgets(input, 2, stdin);  

    const char *killCmd = "kill -9 $(ps -eaf | grep -v grep | grep \" SPR \" | awk '{print $2}')";  
    system(killCmd);  
    return 0;  
} 

用户 ( pmn)cadmn尝试使用此实用程序终止上述进程并失败(如下所示):

pmn@rhel /tmp > ./killSPR  
Before you proceed, find out under which ID I'm running. Hit enter when you are done...  
sh: line 0: kill: (5822) - Operation not permitted  
sh: line 0: kill: (10466) - Operation not permitted  
sh: line 0: kill: (13431) - Operation not permitted  
sh: line 0: kill: (17320) - Operation not permitted  
sh: line 0: kill: (20589) - Operation not permitted  
sh: line 0: kill: (22084) - Operation not permitted  
pmn@rhel /tmp >  

当用户在上面等待回车时,该进程killSPR被检查并被视为以用户身份运行cadmn(如下所示),尽管 killSPR 无法终止进程。

cadmn@rhel /tmp > ps -eaf | grep -v grep | grep killSPR  
cadmn   24851 22918  0 17:51 pts/36   00:00:00 ./killSPR  
cadmn@rhel /tmp >

顺便说一句,主分区nosuid上都没有

pmn@rhel /tmp > mount | grep nosuid
pmn@rhel /tmp >

可执行文件上的 setuid 标志似乎没有达到预期的效果。我在这里想念什么?我是否误解了 setuid 的工作原理?

4

3 回答 3

6

首先,setuid bit简单地允许脚本设置uid. 脚本仍然需要分别在or中调用setuid()orsetreuid()来运行。如果不调用or ,脚本仍将以调用脚本的用户身份运行。real uideffective uidsetuid()setreuid()

避免system并且exec因为他们出于安全原因放弃特权。您可以使用kill()来终止进程。

检查这些。

http://linux.die.net/man/2/setuid

http://man7.org/linux/man-pages/man2/setreuid.2.html

http://man7.org/linux/man-pages/man2/kill.2.html

于 2013-12-19T17:27:07.183 回答
2

你应该用电话代替你system的电话execsystem从 suid 程序运行时,说它的手册会放弃特权。

原因解释在man system

不要在具有 set-user-ID 或 set-group-ID 权限的程序中使用 system(),因为某些环境变量的奇怪值可能会被用来破坏系统完整性。请改用 exec(3) 系列函数,但不要使用 execlp(3) 或 execvp(3)。实际上,system() 在 /bin/sh 是 bash 版本 2 的系统上无法从具有 set-user-ID 或 set-group-ID 权限的程序正常工作,因为 bash 2 在启动时会放弃权限。(Debian 使用修改后的 bash,它在作为 sh 调用时不会这样做。)

如果您替换system为,exec除非您调用,否则您将需要能够使用 shell 语法/bin/sh -c <shell command>,这就是system实际执行的操作。

于 2013-12-17T08:21:39.927 回答
2

查看此链接以使 shell 脚本成为守护程序:

制作shell脚本守护进程的最佳方法?

您可能还想在谷歌上搜索一些“服务的 linux 脚本”,我发现 了一些 关于这个主题的链接。

这个想法是你包装一个shell脚本,其中包含一些基本的东西,允许用户通过调用“服务”类型的脚本来控制作为另一个用户运行的程序。例如,您可以包装/usr/var/myservice/SPRkiller为“服务”脚本,然后可以从任何用户调用它:service SPRkiller start然后SPRkiller运行,终止相应的服务(假设 SPR“程序”以非 root 用户身份运行) .

这听起来像是您正在努力实现的目标。运行一个程序(shell 脚本/C 程序/其他)无论如何都会对它进行相同的用户限制(升级错误/黑客除外)。

附带说明一下,您似乎对 Linux/Unix 上的用户权限以及某些命令和功能的作用略有误解。如果一个用户没有权限做某个动作(比如kill另一个用户的进程),那么调用setuid你想要的程序kill(或它kill自己)将没有任何效果,因为该用户没有权限访问另一个用户的空间' 没有超级用户权限。因此,即使您在 shell 脚本或 C 程序中调用相同的system命令,也会得到相同的效果。

http://www.linux.com/learn/是一个很好的资源,这里是文件权限的链接

希望有帮助

于 2013-12-17T09:25:34.833 回答