有人可以解释 sshd 是如何进行权限分离的吗?

信息安全 SSH
2021-08-29 08:17:50

我对 sshd 如何丢弃传入连接的 privs 感到困惑。我发现这个页面在高层次上提供了非常丰富的信息:

http://www.citi.umich.edu/u/provos/ssh/privsep.html

但是我不明白特权 sshd 的孩子是如何没有特权的。

在我下面的调试中,特权 sshd 是 28389,并调用 clone() 来创建 29266,即无特权的孩子。当我使用 ps 显示 pids 29268 的 UID/EUID 时,正如预期的那样,UID 为 1002,但 29266,sshd 的非特权子项为零,这似乎与上面的链接相矛盾,上面的链接说“这是通过更改其 uid/ 来实现的” gid 给未使用的用户”。

woOt@host:~$ sudo strace -p 28389 -e trace=clone
Process 28389 attached - interrupt to quit
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fb7076d5a90) = 29266
^CProcess 28389 detached
woOt@host:~$
woOt@host:~$
woOt@host:~$ ps auxf | grep sshd
root     28389  0.0  0.0  49944  1244 ?        Ss   18:15   0:00 /usr/sbin/sshd
root     29266  0.0  0.2  54576  3308 ?        Ss   18:37   0:00  \_ sshd: test [priv]
test     29268  0.0  0.0  54576  1440 ?        S    18:37   0:00      \_ sshd: test@pts/2
woOt@host:~$
woOt@host:~$
woOt@host:~$ ps -eo pid,uid,euid | egrep 'PID|28389|29266|29268'
  PID   UID  EUID
28389     0     0
29266     0     0
29268  1002  1002
woOt@host:~$
woOt@host:~$
woOt@host:~$ grep 1002 /etc/passwd
test:x:1002:1003:,,,:/home/test:/bin/bash
woOt@host:~$

编辑问题以正确说明:

监控进程 (2405) 的非特权子 (2406)

根 2370 0.0 1.1 55592 5524 ?SS 00:12 0:00 /usr/sbin/sshd -D
根 2405 0.0 1.1 59008 5720 ?Ss 00:12 0:00 \_ sshd:测试 [priv]
sshd       2406   0.0 0.6 56936 3072 ? S 00:12 0:00 \_ sshd:测试 [网络]

和监控进程认证后的用户特权子 (2419):

根 2370 0.0 1.1 55592 5524 ?SS 00:12 0:00 /usr/sbin/sshd -D
根 2405 0.0 1.1 60224 5756 ?Ss 00:12 0:00 \_ sshd:测试 [priv]
测试      2419   0.0 0.7 60224 3888 ? S 00:12 0:00 \_ sshd: test@pts/1

感谢回答,谢谢

2个回答

29266,无特权的孩子

这个是特权的,正如进程标题所示sshd: test [priv]29268是非特权的 postauth 子(用户已经test是 root)。

但是您可以使用 privsep 的主要地方是身份验证之前:

root     11759  0.0  0.0  69928  6056 ?        Ss   Feb07   0:00 /usr/sbin/sshd -D
root     10071  0.2  0.0 119280  7096 ?        Ss   10:56   0:00  \_ sshd: unknown [priv]
sshd     10072  0.2  0.0  71272  3016 ?        S    10:56   0:00      \_ sshd: unknown [net] 

在那里,您可以看到特权进程在root特权 (10071) 和 net-child (sshd: user [net]下运行,在sshd用户下运行,并且通常在阻止大多数特权升级攻击的沙箱下运行,代码中存在漏洞。

因此,正如 tylerl 已经提到的,或者您setuid习惯于将权限从 root 删除/更改为sshd您的用户。但请注意,在尝试理解这个星座时,您需要指出正确的过程。图片通常超过千字:

图片

在与您的示例对应的图像中的位置:

  • 第一个特权是sshd守护进程(你的 pid 28389
  • 第二个特权是监视器(您的 pid 29266
  • 你没有在你的ps非特权网络孩子(头脑 pid 10072
  • 特权用户是孩子(您的 pid 29268

这是你如何做到的:

您从一个以 root 身份运行的父进程开始。

该进程forks 本身创建了两个相同的克隆,其中只有一个是父进程,一个是子fork进程(父进程返回子进程的 PID,子进程返回 0)。注意:fork是 libc 函数名,在它调用clone的底层是内核提供的系统调用。

在孩子中,您接下来执行任何需要发生的特权操作,根据需要设置环境。

完成所有准备工作后,子进程调用setuid(实际上可能是某些调用的组合,setreuid setregid也可能是其他一些调用)以切换到新的非特权进程所有者的 UID/GID。

最后,子进程调用exec(可能execle或类似的)来运行子进程应该执行的任何程序,用新的进程空间替换当前进程空间,但保持与子进程以前相同的 UID/GID/PID。