While reviewing my Twitter feed I noticed a recent popular tweet from @0xdea.

I was intrigued and wanted to see if there was a way to leverage this to execute arbitrary code as root.

First we need to understand what the value of INT_MAX is. Fortunately the getconf command can be used to find the value or you can find it in /usr/include/limits.h.

[root@localhost ~]# getconf INT_MAX
2147483647

[root@localhost ~]# grep ‘define INT_MAX’ /usr/include/limits.h
# define INT_MAX 2147483647

To exploit the vulnerability the user must have a UID value larger than 2147483647. I used the same value of 4000000000 that @0xdea posted.

[root@localhost ~]# useradd -u 4000000000 user9
[root@localhost ~]# id user9
uid=4000000000(user9) gid=1006(user9) groups=1006(user9)

The first test case I attempted was to manage a service. I successfully started tuned(8) as a low privilege user.
CVE-2018-19788-start-tuned

Now that the vulnerability has been verified I was on a quest to find a way to execute arbitrary code as root. I approached this using the same methodology I use when attacking sudo rules.

  1. Learn about the command(man, info, Google)
  2. Search for options/parameters/functionality to abuse.
    1. Execute commands
    2. Load libraries
    3. File paths
    4. Environment variables
    5. Pipe or store output
    6. Configuration files
    7. Determine if other commands are executed (strace -f,ltrace -f -S)

After paging through the systemctl man page and trying various commands/options, I successfully leveraged the link parameter to deploy a custom service file on a CentOS 7.4 system. I suspect there are other systemctl parameters or options that be abused.

man page excerpt

link FILENAME…

Link a unit file that is not in the unit file search paths into the unit file search path. This requires an absolute path to a unit file. The effect of this can be undone with disable. The effect of this command is that a unit file is available for start and other commands although it is not installed directly in the unit search path.

To achieve arbitrary code execution I copied an existing service file to my test users home directory and modified it. The main line to modify is ExecStart=, however I am sure there are plenty of other options but this was the easy button. The job is not connected to the standard I/O so I piped the output of id to the wall command. Full PoC here: CVE-2018-19788.sh. I asked @paragonsec to independently test it on his Debian system and he confirmed it was successful. Woot!

CVE-2018-19788

UPDATE

@paragonsec discovered a one-liner with the systemd-run command to get a full interactive root shell.

Summary

While this vulnerability should have limited exposure because of the large UID requirement, I still enjoyed the challenge of finding a way to leverage it to execute arbitrary code as root. Props to @0xdea for finding and disclosing the vulnerability. I appreciate @paragonsec for testing my PoC on short notice. My PoC was referenced in The Hacker News Warning! Unprivileged Linux Users With UID > INT_MAX Can Execute Any Command.