Can someone explain how sshd does privilege separation?
29266, the unprivileged child
This one is the privileged one, as the process title shows sshd: test [priv]
, the 29268
is unprivileged postauth child (user is already test
instead of root).
But the main place where you can use privsep is before authentication:
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]
There you see the privileged process running under root
privileges (10071) and net-child (sshd: user [net]
, running under sshd
user, and usually under some sandbox which prevents most of the privilege escalation attacks, it there was a hole in the code.
So as already mentioned by tylerl, or you setuid
is used to drop/change privileges from root to sshd
or your user. But note that you need to point out to the correct process when trying to understand this constellation. Image is usually more than thousands words:
Where in the image corresponding to your example:
- the first privileged is
sshd
daemon (your pid28389
) - the second one privileged is monitor (your pid
29266
) - you don't have in your
ps
unprivileged network child (mind pid10072
) - the user privileged is child (your pid
29268
)
Here's how you do it:
You start out with a parent process, running as root.
That process fork
s itself, creating two identical clones, only one of them is the parent and one is the child (fork
returns the child's PID for the parent process, and 0 for the child). NB: fork
is the libc function name, under the hood it calls clone
which is the syscall provided by the kernel.
In the child, you next perform any privileged operations that need to happen, setting up the environment as desired.
Once all the prep work is done, the child process calls setuid
(actually probably some combination of setreuid
setregid
and possibly a few other calls) to switch to the UID/GID of the new unprivileged process owner.
Lastly, the child calls exec
(probably execle
or similar) to run whatever program the child is supposed to be executing, replacing the current process space with the new one, though keeping the same UID/GID/PID that the child process had before.