linux下程序拥有可以提升root权限,需要提升权限可通过fork子进程去完成
程序员文章站
2022-05-10 09:39:15
...
1.程序拥有可提升root权限的方法
sudo -S setcap cap_setuid+ep 应用程序
如果sudo执行失败,将用户加入sudo权限组中。
2.为了保证每次权限可以多次使用,通过fork子进程去完成相应的任务。
切换权限用户使用的函数是setuid();
#include <stdio.h>
int main()
{
uid_t cur_uid = 0;
cur_uid = getuid();
//切换到root权限
if (setuid(0) < 0)
{
fprintf(stderr, "The switch to root user failed!");
return -1;
}
//执行需要在root权限的操作
//为了安全,将权限降回去
if (setuid(cur_uid) < 0)
{
fprintf(stderr, "Recovery process user failed!");
return -1;
}
return 0;
}
使用上面的代码存在一个问题,将权限提升到root权限的时候执行完相应的操作,在降回去普通用户,将无法再次提升到root权限。想知道详细的可以阅读setuid()的机制。
这里作者实现一个类似popen的可读函数,该函数通过fork出子进程提升到root权限,执行root权限才能执行的命令,通过创建管道的方式,将结果传回给主进程。通过这样的方式,就可以保证主进程的特殊权限一直存在,可以重复使用。
static FILE *readpopen(const char *cmd)
{
int pipefd[2];
int pid_t;
uid_t cur_uid = 0;
if(cmd == NULL)
{
fprintf(stderr,"readpopen() param error");
return NULL;
}
//创建管道
if(pipe(pipefd) < 0)
{
fprintf(stderr, "readpopen() pipe create error");
return NULL;
}
pid_t = fork();
if(pid_t < 0)
return NULL;
if(0 == pid_t)
{
cur_uid = getuid();
if (setuid(0) < 0)
{
fprintf(stderr, "The switch to root user failed!");
return NULL;
}
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]);
execl("/bin/bash", "sh", "-c", cmd, (char *)NULL);
/* Recovery process user privilege */
if (setuid(cur_uid) < 0)
{
fprintf(stderr, "The switch to user failed!");
return NULL;
}
exit(0);
}
waitpid(pid_t, NULL, 0);
close(pipefd[1]);
return fdopen(pipefd[0], "r");
}