2013-12-17 26 views
6

我编写了一个名为killSPR的小型C实用程序,以在我的RHEL盒上终止以下进程。这个想法是任何登录到这个linux系统的人都可以使用这个工具来杀死下面提到的进程(这是行不通的 - 下面会解释)。setuid在可执行文件上似乎不起作用

[email protected] /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 
[email protected] /tmp > 

该实用程序是由用户cadmn(下这些过程运行)所拥有,并且具有的setuid标志在其上设置(如下所示)。

/* 
* 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尝试不同杀与该实用程序的上述处理和失败(如下所示)::

[email protected] /tmp > ls -l killSPR 
-rwsr-xr-x 1 cadmn cusers 9925 Dec 17 17:51 killSPR 
[email protected] /tmp > 

C代码在下面给出

[email protected] /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 
[email protected] /tmp > 

当用户等待点击上面的输入时,过程killSPR被检查,并且看起来像用户cadmn(如下所示),尽管killSPR无法终止进程。

[email protected] /tmp > ps -eaf | grep -v grep | grep killSPR 
cadmn 24851 22918 0 17:51 pts/36 00:00:00 ./killSPR 
[email protected] /tmp > 

顺便说一句,没有一个主分区对他们

[email protected] /tmp > mount | grep nosuid 
[email protected] /tmp > 

上的可执行了setuid标记任何nosuid似乎并没有收到预期的效果。我在这里错过了什么?我误解了setuid的工作原理吗?

+0

是有一个原因,这可能不只是用'777'权限,而不是一个编译的二进制shell脚本? – txtechhelp

+1

@txtechhelp - 带有perms 777的shell脚本不起作用。这就是为什么 - 如果用户'pmn'调用了这个脚本,那么接下来的过程将以用户'pmn'运行,该用户没有权限杀死以用户'cadmn'运行的进程(除非你是root,你不能杀死别人运行的进程)。 顺便说一下,在脚本上设置setuid标志也将不起作用:setuid用一种shell语言编写的脚本被系统忽略为安全功能。因此,这需要一个编译的程序。 希望这回答你的问题。 – pmn

+0

我理解Linux/Unix系统的用户权限和限制,我在问你为什么要通过C程序来做到这一点(如果在单独的登录中作为单独用户运行,它具有相同的限制)已经发布..你只是简单地从C程序中调用系统命令,它与通过shell脚本调用相同命令(在程序中为'kill')具有相同的效果。相反,你所要做的就是想给特定的程序提供'服务控制'给非root用户...如果这是正确的,请更改你的问题 – txtechhelp

回答

1

首先是一个链接,setuid bit只允许一个脚本来设置uid。脚本仍然需要分别拨打setuid()setreuid()来运行real uideffective uid。如果不调用setuid()setreuid(),脚本仍将以调用脚本的用户身份运行。

避免systemexec因为他们为了安全原因而放弃特权。您可以使用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

+0

谢谢。 setreuid做了窍门(尽管setuid没有工作)。尽管如此,这种行为并不一致,原因如下:确切的场景在RHEL盒子上无法正常工作,在我的家用PC上作为虚拟机运行的Mint XFCE 15上没有setuid或setreuid工作! – pmn

+0

'setuid()'和'setr​​euid()'之间的区别是文件的所有权。对于使用'setuid()'的文件,它必须由'root'和'setid bit'拥有。在代码中,setuid()可以切换到包含'root'的任何'uid'。在你的情况下,你想'setuid()'到'cadmn'。如果你想让这个文件被'cadmn'拥有,'setuid()'不会工作,但'setr​​euid()'会。这可能是你所做的。 'setuid()'和'setr​​euid()'手册页讨论了这种差异。 – alvits

1

您应该用exec呼叫替换您的system呼叫。手动system说,它从suid程序运行时,它会放弃权限。

的原因是man system解释说:

不要从一个程序设置用户ID或设置组ID 特权使用system(),因为一些环境变量奇怪的值可能 被用来破坏系统完整性。使用exec(3)系列的函数,而不是execlp(3)或execvp(3)。在 事实上,系统()不会在/ bin/sh是bash版本2的系统上使用set-user-ID或set-group-ID权限的程序正常工作,因为bash 2 在启动时会丢弃权限。 (Debian使用改进的庆典,当运行sh的时候不 没有做到这一点。)

如果用exec替换system你将需要能够除非你打电话/bin/sh -c <shell command>使用shell语法,这是什么,是system实际上在做。

+0

哦,我明白了。让我试试这个并回到你身边。 – pmn

+0

'exec'与'system'具有相同的用户限制。换句话说,如果'userX'没有读/写/执行文件夹'/ blahsy/blah'中的任何权限,那么C调用'system/exec('ls -l/blahsy/blah')'会给一个操作不允许的错误,因为'userX'没有该文件夹的权限..如果你这样做,而不是'system('sudo ls -l/blahsy /这可能是一个不同的故事 – txtechhelp

+0

嗯,那么它看起来像我误解了setuid的权力。你能给我一个场景,我可以使用setuid吗? – pmn

2

退房使得shell脚本中的守护此链接:

Best way to make a shell script daemon?

您可能还需要一些Google 'linux script to service',我founda coupleof links在这个问题上。

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

这听起来就像你试图实现的。运行一个程序(shell脚本/ C程序/无论什么)在它上面都有相同的用户限制,不管什么(除了升级错误/黑客)。

在附注中,您似乎对Linux/Unix上的用户权限以及某些命令和函数所做的操作有轻微的误解。如果用户没有权限执行某个操作(例如kill另一个用户的过程),则在需要kill(或kill本身)的程序上调用setuid将不起作用,因为用户没有权限另一个用户'空间'没有超级用户权限。所以,即使你在shell脚本或C程序中并且调用了相同的命令,你也会得到相同的效果。

http://www.linux.com/learn/是一个很好的资源,这里是为file permissions

希望帮助