Another interesting local privilege escalation vulnerability, PolicyKit this time (and how to avoid)

Luckily, this one takes a bit more ingenuity on behalf of the attacker.

If you can manage to make someone create a user account for you, and assign you with a UID greater than two billion and peanuts (in short, INT_MAX), it's really easy to gain root privileges, because PolicyKit has a flaw in evaluating UIDs.

Let's see how this would work normally:

someuser@host$ id
uid=2015(someuser) gid=2015(someuser) groups=2015(someuser) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
someuser@host$ systemd-run -t /bin/bash Failed to start transient service unit: Interactive authentication required.

This is systemd delegating a transient unit start request to PolicyKit, which says, "Nope. You need to authenticate as superuser before you can do the above."

Let's consider this example - a user named "foo" was created, and they have somehow managed to make their user ID be above two billion and peanuts. Say, three billion. (With enormous multi-tenant environments, that is not such an impossibility, to be honest.)

Let's repeat the above.

foo@host$ id
uid=3000000000(foo) gid=1001(foo) groups=1001(foo) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
foo@host$ systemd-run -t bash
Running as unit run-16691.service.
Press ^] three times within 1s to disconnect TTY.

Again, SELinux to the rescue. If we make local users confined by default, this problem doesn't occur:

root@host# semanage login -l | grep foo
foo                  staff_u              s0                   *
root@host# ssh foo@localhost
foo@host$ id -Z
foo@host$ systemd-run -t /bin/bash
Failed to start transient service unit: Access denied

Even with sysadm_u (which can use sudo and su, but needs special permissions to log in using ssh), the problem is aleviated:

root@host# semanage login -l | grep foo
foo                  sysadm_u             s0                   *
root@host# getsebool -a | grep ^ssh_sysadm
ssh_sysadm_login --> on
root@host# ssh foo@localhost
foo@host$ systemd-run -t /bin/bash
Failed to start transient service unit: Access denied

So here we have it - yet another proof how SELinux keeps your system humming much more securely on a daily basis. Users that need to administer the box can do that using sudo, and in they daily work, they are being protected from malicious use-cases by our good old watchdog.


A black cat crossing the street signifies that the animal is going somewhere.
[don't forget to kudo a helpful post or mark it as a solution!]
1 Reply
Flight Engineer Flight Engineer
Flight Engineer

Super helpful Grega, thanks for sharing that neat stuff.

Join the discussion
You must log in to join this conversation.