Monday, May 18, 2015

System Archaeology Through Testing [feedly]

System Archaeology Through Testing
// Chef Blog

As you may be aware, I have been working on a Chef audit-mode cookbook that implements the CIS Benchmarks. I recently added coverage for Ubuntu 14.04. In this post, I want to share a discovery about OS-level configuration that is inherently against the recommendation from the benchmark, and the way users can remediate this using Chef.

In the CIS Benchmark for Ubuntu 14.04, section 13.7 states:

"Description: While the system administrator can establish secure permissions for users' home directories, the users can easily override these."

"Rationale: Group or world-writable user home directories may enable malicious users to steal or modify other users' data or to gain another user's system privileges."

To implement this in Chef's audit mode, I wrote a control that looks like this:

control_group '13 Review User and Group Settings' do    let(:user_dirs) do      ud = {}      Etc::Passwd.each do |u|        unless (%w(root halt sync shutdown).include?( || =~ /(\/sbin\/nologin|\/bin\/false)/)          ud[] = u.dir        end      end      ud    end      control '13.7 Check Permissions on User Home Directories' do      it 'has correct permissions for all non-system user home directories' do        user_dirs.each_value do |user_dir|          if            expect(file(user_dir)).to_not'group')            expect(file(user_dir)).to_not'others')            expect(file(user_dir)).to_not'others')            expect(file(user_dir)).to_not'others')          end        end      end    end  end

Here, user_dirs is used in some other tests within the control group in the full file. It ensures that we're only looking at the home directories for "non system" users – those who are not specifically root, halt, sync, or shutdown, or users with their shell set to nologin or false. I'm using the "bento" box that we publish for Ubuntu 14.04. Unfortunately, on this default installation, the test fails:

1) 13 Review User and Group Settings 13.7 Check Permissions on User Home Directories has correct permissions for all non-system user home directories     Failure/Error: expect(file(user_dir)).to_not'group')  pected File "/var/lib/libuuid" not to be writable  

This was surprising to me. This is distinctly a "system" home directory, since it is in /var/lib, right? What is this directory, and why is it writable by the group?

$ ls -ld /var/lib/libuuid  drwxrwsr-x 2 libuuid libuuid 4096 Apr 16  2014 /var/lib/libuuid    $ getent passwd | grep /var/lib/libuuid  libuuid:x:100:101::/var/lib/libuuid:

There is a libuuid "system" user – it has a low UID/GID. But what is creating the user and this directory? One might think there's a libuuid package that creates this directory, as that is customary on Debian-based systems.

$ dpkg -S /var/lib/libuuid  dpkg-query: no path found matching pattern /var/lib/libuuid

No package owns this directory. We do have two "uuid" packages installed:

$ dpkg -l | grep uuid  ii  libuuid1:amd64 2.20.1-5.1ubuntu20  amd64 Universally Unique ID library  ii  uuid-runtime   2.20.1-5.1ubuntu20  amd64 runtime components for the Universally Unique ID library

These are part of the larger util-linux package. Since the packages themselves don't manage this directory, perhaps there's a postinst script that does.

$ grep /var/lib/libuuid /var/lib/dpkg/info/*.postinst  libuuid1:amd64.postinst:   useradd -d /var/lib/libuuid -K UID_MIN=$FIRST_SYSTEM_UID -K UID_MAX=$LAST_SYSTEM_UID -g libuuid libuuid  libuuid1:amd64.postinst:mkdir -p /var/lib/libuuid  libuuid1:amd64.postinst:chown libuuid:libuuid /var/lib/libuuid  libuuid1:amd64.postinst:chmod 2775 /var/lib/libuuid  libuuid1:amd64.postrm: rm -rf /var/lib/libuuid  uuid-runtime.postinst:   Useradd -d /var/lib/libuuid -K UID_MIN=1 -K UID_MAX=499 -g libuuid libuuid

Once the libuuid1 package is installed, it creates the libuuid user, makes its home directory, sets the owner and group, and then sets the permission to 2775. This mode causes the audit control test to fail, because it is group writable. This isn't unusual, other packages in Ubuntu/Debian (and RHEL, to be fair), will create user for the package, or a service it provides, and may perform other system changes.

How do we remediate this finding? Can we just remove the offending packages?

$ sudo dpkg --purge libuuid1 uuid-runtime  dpkg: dependency problems prevent removal of libuuid1:amd64:   rsyslog depends on libuuid1 (>= 2.16).   util-linux depends on libuuid1 (>= 2.16).   libcryptsetup4 depends on libuuid1 (>= 2.16).   e2fsprogs depends on libuuid1 (>= 2.16).   libblkid1:amd64 depends on libuuid1 (>= 2.16).   wget depends on libuuid1 (>= 2.16).   libxapian22 depends on libuuid1 (>= 2.16).   libparted0debian1:amd64 depends on libuuid1 (>= 2.16).    dpkg: error processing package libuuid1:amd64 (--purge):   dependency problems - not removing  (Reading database ... 48682 files and directories currently installed.)  Removing uuid-runtime (2.20.1-5.1ubuntu20) ...  Purging configuration files for uuid-runtime (2.20.1-5.1ubuntu20) ...  Processing triggers for man-db ( ...  Errors were encountered while processing:   libuuid1:amd64

Here, uuid-runtime is removed cleanly. However, libuuid1 is an dependency of other essential packages, and it's the one that has a postrm that cleans up this directory. At this point, we still won't pass the control (13.7) with the uuid-runtime package removed. There are a few possible remediations we can try.

  1. Remove the libuuid user/group. This may cause some libraries to fail, as it's not clear why libuuid1 creates this user.
  2. Change the permission on the /var/lib/libuuid to remove the offending permission, g+ws.
  3. Change the home directory for the libuuid user to something else that doesn't have group write permission. This may have unintended side effects though, for programs that write to the home directory of libuuid directly (since it's in /var/lib).
  4. Change the audit mode test to allow the libuuid user, similar to how it allows the root, halt, sync, or shutdown users.
  5. Set a non-login shell for the libuuid user. I opened a bug for Ubuntu 14.04 proposing this. It's fixed in later versions of Ubuntu, by way of import from Debian (version 8, recently released).

Since the audit-cis cookbook itself only implements audit mode tests, it does no remediation of findings. It's up to end users to correct this in their own cookbooks.

user 'libuuid' do    shell '/bin/false'    home '/var/lib/libuuid'    system true  end

The newly published libuuid-user cookbook serves to remediate the issue by managing the libuuid user, and also provide two levels of validation:

  1. Use audit mode to verify that the user's shell is /bin/false.
  2. Use Serverspec to verify that the root user cannot su to the libuuid user.

It's important to know that none of this addresses that the postinst does not specify a UID for the libuuid user, nor a GID for the libuuid group. In testing this, I uninstalled the uuid-runtime package (as output above shows), but reinstalled it, which recreated the user. The UID was different, but the home directory already existed without modification. This caused the control "13.13 check user home directory ownership" to fail. The recipe in the libuuid-user cookbook mentioned above does not handle this, as it is an unlikely scenario, but it's something to be aware of when considering the list of potential remediation steps above.


Shared via my feedly reader

Sent from my iPhone