Wednesday, February 5, 2020

Sudo cmd contains major security flaw in Linux/MacOs unpatched for last 9 years - buffer overrun allows privileged execution

Sudo, a utility found in all of Linux/Unix/MacOS operating systems, just got a patch  for a major vulnerability that allows unprivileged users to easily obtain unfettered root privileges for last 9 years. 

Exploiting the bug does not require sudo permissions, merely that pwfeedback be enabled. 

Ironically, pwfeedback was meant to make life a bit more secure for users. When enabled, it prints asterisks (*) to the screen when you enter your sudo password.

The good news is pwfeedback isn't enabled by default. The bad news is that sysadmins often do enable it. Worse still, it's enabled by default in at least two popular Linux distributions, Elementary OS and Linux Mint. This also applies to Windows Subsystem for Linux. SUSE WSL is not enabled by default. 

If there is no patch available for your operating system, you can fix the problem by deactavating pwfeedback. First check to see if you're vulnerable by running the command:

sudo -l
Matching Defaults entries for username on xxx-desktop:pwfeedback, env_reset, mail_badpass, ....

If you see  pwfeedback listed in the "Matching Defaults entries" output, you're vulnerable.

To fix it, edit the sudoers file, which is usually located in
/etc/sudoers, and change: 

Defaults pwfeedback


Defaults !pwfeedback

Exploiting the bug

The bug can be reproduced by passing a large input to sudo via a pipe when it prompts for a password. For example:

    $ perl -e 'print(("A" x 100 . "\x{00}") x 50)' | sudo -S id
    Password: Segmentation fault

(( EUID )) && { echo 'Run this script with root priviliges.'; exit 1; } || echo 'Running as root, starting service...'

There are two flaws that contribute to this vulnerability:

  1. The pwfeedback option is not ignored, as it should be, when reading from something other than a terminal device. Due to the lack of a terminal, the saved version of the line erase character remains at its initialized value of 0.
  2. The code that erases the line of asterisks does not properly reset the buffer position if there is a write error, but it does reset the remaining buffer length. As a result, the getln() function can write past the end of the buffer.
On systems with unidirectional pipes, an attempt to write to the read end of the pipe will result in a write error. Because the remaining buffer length is not reset correctly on write error when the line is erased, a buffer on the stack can be overflowed.

The sudo version history shows that the vulnerability was introduced in 2009 and remained active until 2018, with the release of 1.8.26b1. Systems or software using a vulnerable version should move to version 1.8.31 as soon as practical.


No comments:

Post a Comment