CVE-2015-5602 - Unauthorized Privilege Escalation

Bug #1512781 reported by Dmitry Lapshin on 2015-11-03
258
This bug affects 1 person
Affects Status Importance Assigned to Milestone
sudo
Unknown
Unknown
sudo (Debian)
Fix Released
Unknown
sudo (Ubuntu)
Undecided
Unassigned
Precise
Undecided
Unassigned
Trusty
Undecided
Unassigned
Vivid
Undecided
Unassigned
Wily
Undecided
Unassigned
Xenial
Undecided
Unassigned

Bug Description

https://www.exploit-db.com/exploits/37710/

As descpribed in the link above, sudo versions lower or equal than 1.8.14 have a security issue: user with root access to a path with more than one wildcard can access forbidden files such as /etc/shadow, because sudoedit (sudo -e) does not verifiy full path of accessed file:

(quote from link above)

It seems that sudoedit does not check the full path if a wildcard is used
twice (e.g. /home/*/*/file.txt), allowing a malicious user to replace the
file.txt real file with a symbolic link to a different location (e.g.
/etc/shadow).

As an expample,

1. Give user `usr' right to edit some his files:

usr ALL=(root) NOPASSWD: sudoedit /home/*/*/test.txt

2. Under usr, create ~/temp directory, and then create a symblink ~/temp/test.txt to /etc/shadow

3. Perform sudoedit ~/temp/test.txt - you will able to access /etc/shadow.

What realease is affected: tested on all supported now Ubuntu versions. For personaly me, it's 14.04 LTS.

What version is affected: as mentioned, all versions <=1.8.14. For personally me, it's 1.8.9p5

What was expected and happend instead: sudoedit should check full real path, but it didn't.

CVE References

description: updated
summary: - CVE-2015-5602 - Unauthorized Privilege
+ CVE-2015-5602 - Unauthorized Privilege Escalation
information type: Private Security → Public Security
Changed in sudo (Ubuntu Precise):
status: New → Confirmed
Changed in sudo (Ubuntu Trusty):
status: New → Confirmed
Changed in sudo (Ubuntu Vivid):
status: New → Confirmed
Changed in sudo (Ubuntu Wily):
status: New → Confirmed
Changed in sudo (Ubuntu Xenial):
status: New → Confirmed
Revision history for this message
Seth Arnold (seth-arnold) wrote :

I'm a little surprised this got a CVE number to be honest; allowing users to edit files via some privileged mechanism when they may control some portion of the filesystem under consideration is always going to be dangerous.

sudo cannot actually prevent this -- for example, the patch for this issue http://www.sudo.ws/repos/sudo/rev/9636fd256325 (look for the sudo_edit.c hunk) just uses O_NOFOLLOW to try to mitigate this issue:

+#ifdef O_NOFOLLOW
+static int
+sudo_edit_open(const char *path, int oflags, mode_t mode, int sflags)
+{
+ if (!ISSET(sflags, CD_SUDOEDIT_FOLLOW))
+ oflags |= O_NOFOLLOW;
+ return open(path, oflags, mode);
+}
+#else

But O_NOFOLLOW only functions on the final component of a pathname, so you can still edit e.g. /etc/shadow if you create a symlink "ln -s /etc etc".

I'm pretty sure the sudo patch is more or less worthless; here's a far simpler program to test with:

| #include <sys/types.h>
| #include <sys/stat.h>
| #include <fcntl.h>
| #include <stdio.h>
|
| int main(int argc, char* argv[]) {
| int fd;
| int err = 0;
| int i;
|
| for (i=0; i<argc; i++) {
| fd = open(argv[i], O_RDONLY | O_NOFOLLOW);
| if (fd < 0) {
| fprintf(stderr, "open %s failed: %m\n", argv[i]);
| err++;
| } else {
| close(fd);
| }
| }
|
| return err;
| }

(Sorry for the pipes, launchpad collapsed all the spacing, making it illegible.)

$ make o_nofollow
cc o_nofollow.c -o o_nofollow
$ mkdir tests
$ cd tests
$ ln -s /etc etc
$ ln -s /etc/passwd passwd
$ ln -s /etc/shadow shadow
$ ../o_nofollow /etc/passwd /etc/shadow ./etc/passwd ./etc/shadow ./passwd ./shadow
open /etc/shadow failed: Permission denied
open ./etc/shadow failed: Permission denied
open ./passwd failed: Too many levels of symbolic links
open ./shadow failed: Too many levels of symbolic links
$

Note that opening ./etc/passwd succeeded here because ./etc is a symlink to /etc and O_NOFOLLOW does not prevent this.

The #else portion of the code may be fine, I haven't studied it extensively, so there may be some way to salvage the patch. But I suspect it's never going to be perfect.

Thanks

Revision history for this message
Seth Arnold (seth-arnold) wrote :

Ah, the demo program is still illegible only now with pipes. Sigh. I've attached the program here.

Changed in sudo (Debian):
status: Unknown → Confirmed
Revision history for this message
Raphaël Hertzog (hertzog) wrote :

> The #else portion of the code may be fine, I haven't studied it extensively

I doubt this, it relies on comparing inode numbers and devices numbers returned by lstat() and fstat(). lstat() just like O_FOLLOW only considers the final component of the path. If it's a symlink, it returns data about the symlink otherwise it returns data about the file (even though it's accessed through symlinks).

Changed in sudo (Debian):
status: Confirmed → Fix Released
Revision history for this message
Marc Deslauriers (mdeslaur) wrote :

Xenial now has 1.8.16, marking released.

Changed in sudo (Ubuntu Xenial):
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public Security information  Edit
Everyone can see this security related information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.