标签: setuid

set-uid的安全问题和ELF中INTERP(动态链接器)的相对路径

set-uid和ELF二进制文件的INTERP部分中的相对路径的组合非常危险.

我不太清楚应该如何以及在哪里报告此问题,但在我看来,这似乎是关于linux/glibc中的动态链接如何工作的一般安全问题,所以让我解释一下它是什么:

考虑构建动态链接的二进制文件并在ELF INTERP部分中指定相对路径(使用--dynamic-linker gcc选项),这样您就可以使用动态链接的商业应用程序重新分发自定义glibc版本(不允许您静态链接)反对LGPL glibc,但仍然需要让你的二进制工作跨不同的linux发行版具有不同的glibc版本).

如果你将二进制文件chown到root,并将set-uid标志放在你的二进制文件上,它实际上就变成了rootkit.从其他目录执行它时,允许您替换将以root权限执行的动态链接器可执行文件.

为了演示这一点,请查看以下C代码(issue.c):

#include <stdio.h> 

// 
// build with: 
//   gcc -DNAME=\"vulnarable\" -o issue -Wl,--dynamic-linker,.lib64/ld-linux-x86-64.so.2 issue.c 
//   sudo chown root issue 
//   sudo chmod u+s issue 
// now build some code to be executed with root permissions (we use the same issue.c): 
//   mkdir -p .lib64/ 
//   gcc -DNAME=\"rootkit\" -o .lib64/ld-linux-x86-64.so.2 --static issue.c 
// 

int main(int argc, char* argv[]) 
{ 
    printf("(%s) euid:%d\n", NAME, geteuid()); 
} 
Run Code Online (Sandbox Code Playgroud)

如果你现在像这样执行set-uid二进制文件

./issue
Run Code Online (Sandbox Code Playgroud)

甚至只是这样做

ldd issue
Run Code Online (Sandbox Code Playgroud)

而不是得到你可能期望的,例如:

(vulnarable) euid:0
Run Code Online (Sandbox Code Playgroud)

你得到:

(rootkit) …
Run Code Online (Sandbox Code Playgroud)

linux security glibc setuid dynamic-linking

6
推荐指数
1
解决办法
1034
查看次数

在C中运行setuid程序的正确方法

我有一个权限为4750的进程.我的Linux系统中存在两个用户.root用户和appz用户.该进程继承了以"appz"用户身份运行的进程管理器的权限.

我有两个基本的例程:

void do_root (void)
{
        int status;
        status = seteuid (euid);
        if (status < 0) { 
        exit (status);
        }    
}

/* undo root permissions */
void undo_root (void)
{
int status;
        status = seteuid (ruid);
        if (status < 0) { 
                exit (status);
        }
        status = setuid(ruid);
        if (status < 0) { 
                exit (status);
        }
}
Run Code Online (Sandbox Code Playgroud)

我的流程如下:

int main() {
 undo_root();
 do some stuff;
 do_root();
 bind( port 80); //needs root perm
 undo_root();
 while(1) {

    accept commads()
    if ( commands needs …
Run Code Online (Sandbox Code Playgroud)

c linux security setuid

6
推荐指数
2
解决办法
2万
查看次数

可执行文件上的setuid似乎不起作用

我写了一个小的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 …
Run Code Online (Sandbox Code Playgroud)

c linux setuid process

6
推荐指数
1
解决办法
6340
查看次数

从Ruby on Rails执行系统任务的最佳方法是什么?

我正在构建一个小型系统管理Web应用程序(想想Web-Min,但在RoR中),我需要能够从我的Ruby代码访问系统参数.例如,我想允许用户更改服务器的主机名,时区或网络配置.

我目前的想法是有一个单独的setuid脚本(Perl,Ruby,??),以便我可以从我的RoR代码调用它,它将执行操作.这非常麻烦而且不是很优雅.我是一个Ruby新手,想知道是否有更好的方法来完成这类事情.

谢谢!

ruby setuid ruby-on-rails

5
推荐指数
1
解决办法
810
查看次数

用setuid运行git'post-receive'钩子失败了

我有一个git存储库,需要以sudo的形式运行post-receive hook.我编译为测试它的二进制文件如下所示:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main() {
   int ret;
   ret = setuid(geteuid());
   if(!ret) {
      fprintf(stderr, "error setting uid %d \n", ret);
   }       
   system("[...command only sudo can access...]");

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

geteuid()检索的所有者ID post-receive,然后试图对setuid.当与任何用户(包括超级用户)一起运行时,它以root身份正确运行脚本.但是,当由git hook触发时,系统无法设置uid.我试过运行chmod u+s post-receive 我也尝试了一些其他配置,但我的想法已经用完了.除非git触发它,否则它会在所有情况下都有效?

顺便说一句,平台Ubuntu Server 9.04(2.6.28-15),git1.6.0.4,gcc版本4.3.3(Ubuntu 4.3.3-5ubuntu4)

c++ git permissions ubuntu setuid

5
推荐指数
1
解决办法
1025
查看次数

setuid包装器的注意事项

我编写的Python扩展需要root访问才能执行单个硬件初始化调用.我宁愿不以root身份运行整个脚本只是为了我的扩展中的这一个调用,所以我想编写一个包装器来执行此初始化,然后再下载到用户权限并运行实际脚本.

我打算让这个包装器运行sudo,例如

$ sudo devwrap python somescript.py
Run Code Online (Sandbox Code Playgroud)

我正在考虑类似的东西(更新以修复几个错误):

int main(int argc, char * argv[])
{
  if(argc < 2) return 0;

  int res = do_hardware_init();
  if(res != OK_VALUE)
  {
    // Print error message
    return HW_ERR;
  }

  const char *sudo_uid = getenv("SUDO_UID");
  if(sudo_uid)
  {
      int real_uid = (int) strtol(sudo_uid, NULL, 0);
      setuid(real_uid);
  }

  return execvp(argv[1], &argv[1]); // No return if successful

}
Run Code Online (Sandbox Code Playgroud)

所以我有三个问题:

  1. 这看起来很健康吗?我通常不需要弄乱*uid()调用,所以我不熟悉常见的陷阱.这个execvp电话看起来有点奇怪,但据我所知它在正确的地方有争议).
  2. execvp手册页说"不应该直接通过应用程序访问环境数组" - 这是否会使getenv调用成为一个坏主意?
  3. 是否有更好的通话execvp,所以我可以这样做sudo …

c setuid

5
推荐指数
1
解决办法
1174
查看次数

我可以将argv从main传递给execv吗?

execv()函数需要一个NULL终止字符串数组,但不接受参数数量.它使用标记值(NULL指针)来确定数组何时结束.

execv()各州的手册页......

按照惯例,第一个参数应指向与正在执行的文件关联的文件名.指针数组必须由NULL指针终止.

......所以我的问题是......

我想通过argvmain()execv().

我能确定进入main的argv是由NULL指针终止的吗?也就是说,我可以放心,argv[argc] == NULL还是我分配我自己的char*尺寸阵列argc+ 1,并把NULLargc指数?

如果我可以放心,它是否在某处记录?

谢谢,〜埃里克

c program-entry-point setuid exec argv

5
推荐指数
1
解决办法
1469
查看次数

setuid等效于非root用户

Linux有一些类似于setuid的 C接口,它允许程序使用例如用户名/密码切换到不同的用户吗?setuid的问题在于它只能由超级用户使用.

我正在运行一个简单的Web服务,它需要作为登录用户执行作业.因此主进程以root身份运行,并在用户登录后分叉并调用setuid切换到相应的uid.但是,我对以root运行的主进程不太熟悉.我宁愿让它作为另一个用户运行,并且有一些机制可以切换到另一个类似的用户su(但是没有启动新进程).

c linux ubuntu setuid linux-kernel

5
推荐指数
2
解决办法
4325
查看次数

如何递归设置权限,文件夹为700,文件为600,不使用查找

我试图找出一种方法来为递归设置权限700为特定路径上的目录和子目录和文件600.我会使用这些命令:

find/path -type d -print0 | xargs -0 chmod 700

find/path -type f -print0 | xargs -0 chmod 600

但是用户没有运行"find"命令的权限.作为一种解决方法,我尝试使用setuid sticky bit设置包含来自root用户的上述命令的脚本,以便它将以root权限运行(例如普通用户以root权限运行的passwd或sudo命令):

chmod 4755 script.sh

但是我无法从有限的用户帐户执行脚本,它仍然说我没有运行find命令的权限.

有没有人知道如何在不使用"查找"命令的情况下完成此操作?

编辑:操作系统:Centos 6.5

linux permissions setuid find chmod

5
推荐指数
1
解决办法
1671
查看次数

以root身份执行命令而不使用root密码或sudo

我理解以root身份运行脚本的含义,尤其是Web应用程序.但是作为我的Web应用程序的一部分,我需要使用cur的tor,这需要偶尔重置tor ip.在重新启动服务时,tor可以获得新的ip service tor restart.由于只有root可以做到这一点,我编写了一个C包装器脚本来完成我需要的工作,并编译它并在其上设置setuid root,并更改为root用户所有权.但是,当它作为非特权用户运行时,它仍然会询问root密码.作为root用户,服务重启不应该询问密码.

我的剧本:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

void ExecAsRoot (char* str);
int main ()
{
  setuid (0);
  setvbuf(stdout, NULL, _IONBF, 0);
  printf ("Host real ip is: ");
  ExecAsRoot("ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d'/'");
  ExecAsRoot("/usr/sbin/service tor restart");
  // sleep(2);
  printf ("Tor should have switched to a new ip by now.\nNew ip is: ");
  ExecAsRoot("torify curl ifconfig.co 2>/dev/null");
  return 0;
 }

void ExecAsRoot …
Run Code Online (Sandbox Code Playgroud)

c linux setuid root

5
推荐指数
1
解决办法
428
查看次数