【问题标题】:how to execute a command as root如何以root身份执行命令
【发布时间】:2013-07-23 23:18:18
【问题描述】:

我在 Linux (Debian) 上开发了一个 C 代码。有时候,我需要通过system()执行一些命令

我想知道是否可以通过system()作为root 执行命令。如果不是这样,是否有任何函数可以以 root 身份执行命令(或运行二进制文件),我可以在 C 代码上使用?

【问题讨论】:

  • 全球的 Unix 和 Linux 用户最好不要这样。
  • 如果任何用户都可以在没有额外授权的情况下以root身份执行代码,那么区分不同用户的意义何在

标签: c linux root


【解决方案1】:

我们之前遇到过想用普通用户执行root命令的情况,下面是我们的解决方案(使用setuid/SUID):

假设:

  • 用户名Tom
  • 群组gTom
  • C 程序文件my_pro.c

第一步:编写C代码工具:my_sudo.c

...
int main(int args, char *argv[]) {
    if (args < 2) 
        printf("Usage: my_sudo [cmd] [arg1 arg2 ...]");

    // cmd here is the shell cmd that you want execute in "my_pro"
    // you can check the shell cmd privilege here
    // example:  if (argv[1] != "yum") return; we just allow yum execute here

    char cmd[MAX_CMD];
    int i;
    for ( i = 2; i < args; i ++) {
    // concatenate the cmd, example: "yum install xxxxx"
        strcat(cmd, " ");
        strcat(cmd, argv[i]);
    }

    system(cmd);
} 

第二步:编译my_sudo.c得到my_sudo的可执行文件

   sudo chown root:gTom my_sudo   // user root && gTom group
   sudo chmod 4550 my_sudo        // use SUID to get root privilege

   #you will see my_sudo like this(ls -l)
   #-r-sr-x--- 1 root my_sudo 9028 Jul 19 10:09 my_sudo*

   #assume we put my_sudo to /usr/sbin/my_sudo

第 3 步:在您的 C 代码中

...
int main() {
    ...
    system("/usr/bin/mysudo yum install xxxxx");
    ...
}

#gcc && ls -l
#-rwxr--r--  1 Tom gTom 1895797 Jul 23 13:55 my_pro

第四步:执行./my_pro

您可以在没有sudo 的情况下执行yum install

【讨论】:

  • ⚠ 哎哟!您将参数连接为 shell 命令行!然后用户可以执行mysudo 'arg;sh' 来获取root 例如外壳。而且您不会像sudo 那样对环境进行消毒。
【解决方案2】:

如果您是系统上拥有sudo 权限以以root 身份运行命令的用户,只需在命令前附加sudo

system("sudo yum install some-package");

如果您希望任何人都能够做到这一点,那么您必须是您系统的管理员,将文件的所有者更改为root,并将您的可执行文件的权限修改为以root 运行。通过这样做,您无需使用sudo 修改您的system() 命令字符串。

chmod +s my_program
chown root my_program

意识到这样做可能会给你带来安全问题,除非你已经证明你的程序没有安全问题。

文件系统可能不允许您在程序上设置setuid 位。如果您需要有关这些方面的更多信息,请咨询SuperUser

【讨论】:

  • 如果程序是由非root用户启动的,是否可以通过C代码传递root密码来获得root权限?那怎么办?
  • 如果您假设用户拥有 root 密码,那么他们可以自己以 root 身份运行命令。
  • 我知道可以以root身份运行可执行程序,然后程序将拥有调用函数的root权限。但是我想知道当程序以非root身份启动时,是否可以通过使用C或Posix函数获得root权限来执行命令。
  • 如果程序没有写成 SUID-root 程序,简单地使其成为 SUID-root 可能会导致重大的安全问题。很少有没有特别考虑到 SUID-root 状态的程序在设置为 SUID-root 时是安全的(而且那些安全的程序通常不需要首先是 SUID-root)。
  • 没有可以将 EUID 从非 root 更改为 root 的 函数 — 除非程序最初以 root 身份启动,因此保存的 UID 为 root。有关详细信息,请参阅 getuid()setuid() 和亲属。运行sudo 程序作为您要执行的命令的前缀是唯一合理的方法。 (有各种或多或少疯狂的方法,但以 root 身份运行的程序是责任,主要责任)。
【解决方案3】:

这是需要牢记的其中一项技巧。存在安全风险,因此请注意谁将使用它。在“系统”命令中,您甚至可以执行外部脚本……尽管这会带来重大的安全风险,因为虽然每次编译时都必须重新设置此二进制文件的权限,但脚本可以无休止地更改,并且此二进制文件将继续调用它。

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

//Create as root
//gcc fixmusic.c -o fixmusic 
//chmod u+s fixmusic
//now run as non-root user and it should work despite limitations of user


int main(int argc, char *argv[] )
{

    setuid(0);

    char command[100];
    sprintf(command,"/usr/bin/chmod -R a+w /mnt/Local/Music");
    system(command);
    //This is just optional info if someone cat's the binary
    volatile const char comment [] = "INFO: Fixes music permissions";
    return 0;
}

【讨论】:

    猜你喜欢
    • 2012-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多