Metasploit Module: Apport / ABRT chroot Privilege Escalation
Type: exploit
Path: modules/exploits/linux/local/apport_abrt_chroot_priv_esc.rb
Disclosure date: 2015-03-31
References: CVE-2015-1318, URL-http://www.openwall.com/lists/oss-security/2015/04/14/4, EDB-36782, EDB-36746, URL-https://gist.github.com/taviso/0f02c255c13c5c113406, URL-https://bugzilla.redhat.com/show_bug.cgi?id=1211223, URL-https://bugzilla.redhat.com/show_bug.cgi?id=1211835, URL-https://usn.ubuntu.com/usn/USN-2569-1/, URL-https://code.launchpad.net/~stgraber/apport/pidns-support/+merge/200893, URL-https://bugs.launchpad.net/ubuntu/+source/apport/+bug/1438758

Description:
This module attempts to gain root privileges on Linux systems by
          invoking the default coredump handler inside a namespace ("container").

          Apport versions 2.13 through 2.17.x before 2.17.1 on Ubuntu are
          vulnerable, due to a feature which allows forwarding reports to
          a container's Apport by changing the root directory before loading
          the crash report, causing `usr/share/apport/apport` within the crashed
          task's directory to be executed.

          Similarly, Fedora is vulnerable when the kernel crash handler is
          configured to change root directory before executing ABRT, causing
          `usr/libexec/abrt-hook-ccpp` within the crashed task's directory to be
          executed.

          In both instances, the crash handler does not drop privileges,
          resulting in code execution as root.

          This module has been tested successfully on Apport 2.14.1 on
          Ubuntu 14.04.1 LTS x86 and x86_64 and ABRT on Fedora 19 and 20 x86_64.

Check method (fingerprinting):
unless userns_enabled?
      vprint_error 'Unprivileged user namespaces are not permitted'
      return CheckCode::Safe('Unprivileged user namespaces are not permitted')
    end
    vprint_good 'Unprivileged user namespaces are permitted'

    kernel_version = Rex::Version.new kernel_release.split('-').first

    if kernel_version < Rex::Version.new('3.12')
      vprint_error "Linux kernel version #{kernel_version} is not vulnerable"
      return CheckCode::Safe("Kernel version #{kernel_version} is not vulnerable")
    end
    vprint_good "Linux kernel version #{kernel_version} is vulnerable"

    kernel_core_pattern = read_file('/proc/sys/kernel/core_pattern').to_s

    # Vulnerable core_pattern (abrt):
    #   kernel.core_pattern = |/usr/sbin/chroot /proc/%P/root /usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e
    # Patched systems no longer preface the command with /usr/sbin/chroot
    #   kernel.core_pattern = |/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e
    if kernel_core_pattern.include?('chroot') && kernel_core_pattern.include?('abrt-hook-ccpp')
      vprint_good 'System is configured to chroot ABRT for crash reporting'
      return CheckCode::Appears('System is configured to chroot ABRT for crash reporting')
    end

    # Vulnerable core_pattern (apport):
    #   kernel.core_pattern = |/usr/share/apport/apport %p %s %c %P
    if kernel_core_pattern.include? 'apport'
      vprint_good 'System is configured to use Apport for crash reporting'

      unless command_e