简单实现无需密码 sudo

sudo 原理

详细介绍参考这里sudo命令实现原理简析
以下简单介绍下关键的部分!

SUID 的概念

What is SUID and how to set it in Linux?
SUID (Set owner User ID up on execution) is a special type of file permissions given to a file. Normally in Linux/Unix when a program runs, it inherits access permissions from the logged in user. SUID is defined as giving temporary permissions to a user to run a program/file with the permissions of the file owner rather that the user who runs it. In simple words users will get file owner‘s permissions as well as owner UID and GID when executing a file/program/command.

如上 suid(Set owner User ID up on execution) 概念就是:如果文件被设置了suid属性,那么运行时候,这个程序的权限就会以文件拥有所有者的权限来运行。所以如果这个文件的所有者是 root 那么这个文件将以 root 权限运行!!!


具有 suid 的程序在 ls -la 时候能看到一个 s 属性。这个属性用 chmod +4000 或者 chmod +s 都可以添加!

setuid 函数

如下摘取自 man setuid:

PROLOG
       This  manual  page  is  part of the POSIX Programmer's Manual.  The Linux implementation of this interface may
       differ (consult the corresponding Linux manual page for details of Linux behavior), or the interface  may  not
       be implemented on Linux.

NAME
       setuid — set user ID

SYNOPSIS
       #include <unistd.h>

       int setuid(uid_t uid);

DESCRIPTION
       If  the  process  has  appropriate privileges, setuid() shall set the real user ID, effective user ID, and the
       saved set-user-ID of the calling process to uid.

       If the process does not have appropriate privileges, but uid is equal to the real user ID or  the  saved  set-
       user-ID,  setuid() shall set the effective user ID to uid; the real user ID and saved set-user-ID shall remain
       unchanged.

       The setuid() function shall not affect the supplementary group list in any way.

RETURN VALUE
       Upon successful completion, 0 shall be returned. Otherwise, -1 shall be returned and errno set to indicate the       error.

sudo 简单实现

最关键的一步就是调用setuid函数把 uid 设置为 0,即 root。这一步能成功在于,程序具有 suid 属性,他的 euid 是 0(root)所以能成功执行 setuid 函数。

代码如下:

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

int main(int argc, char **argv)
{
    if (setuid(0))
        return -1;

    if (argc > 1)
        execvp(argv[1], argv + 1);
    else
        return -1;
}

如下是执行log

posted @ 2021-01-15 19:59  sinpo828  阅读(198)  评论(0编辑  收藏  举报